├── .eslintignore ├── .eslintrc.js ├── .github └── workflows │ ├── ci-workflow.yml │ └── codeql-analysis.yml ├── .gitignore ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── DCO ├── Jenkinsfile ├── LICENSE ├── README.features.md ├── README.md ├── TUTORIAL.md ├── USAGE_DATA.md ├── build ├── build-snippets.ts ├── build-svg-icons.ts ├── install-vscode.ts ├── unit-tests.ts └── verify-tools.ts ├── coverconfig.json ├── header.js ├── images ├── C.svg ├── CT.svg ├── CTB.svg ├── EL.svg ├── PL.svg ├── PLR.svg ├── PR.svg ├── T.svg ├── TB.svg ├── TR.svg ├── TT.svg ├── cancelled.png ├── dark │ ├── build.svg │ ├── debug-alt-small.svg │ ├── debug-continue.svg │ ├── debug-stop.svg │ ├── go-to-file.svg │ ├── go-to-task.svg │ ├── icon-close.svg │ ├── icon-delete.svg │ ├── icon-diagram.svg │ ├── icon-focus.svg │ ├── icon-issue.svg │ ├── icon-refresh.svg │ ├── icon-reset.svg │ ├── preview-right.svg │ └── versions.svg ├── debug-alt-small.svg ├── debug-continue.svg ├── debug-pause.svg ├── debug-stop.svg ├── generated │ ├── error │ │ ├── C.svg │ │ ├── PLR.svg │ │ └── TR.svg │ └── pending │ │ ├── C.svg │ │ ├── PLR.svg │ │ └── TR.svg ├── gif-tekton │ ├── add-trigger.gif │ ├── auto-refresh.gif │ ├── code-completion.gif │ ├── create-pvc-workspaces.gif │ ├── create-workspace-pvc.gif │ ├── demo.gif │ ├── deploy-resource.gif │ ├── go-to-defination.gif │ ├── pipeline-diagram.gif │ ├── restart-pipeline.gif │ ├── show-logs-in-editor.gif │ ├── start-pipeline.gif │ ├── start-workspaces.gif │ ├── tekton-hub-cluster.gif │ └── tekton-hub.gif ├── light │ ├── build.svg │ ├── debug-pause.svg │ ├── go-to-file.svg │ ├── go-to-task.svg │ ├── icon-close.svg │ ├── icon-delete.svg │ ├── icon-diagram.svg │ ├── icon-focus.svg │ ├── icon-issue.svg │ ├── icon-refresh.svg │ ├── icon-reset.svg │ ├── preview-right.svg │ └── versions.svg ├── pending.svg ├── running.gif ├── tekton.png ├── tekton.svg ├── tkn-down.png └── walkthrough │ ├── create-resource.gif │ ├── debug.gif │ ├── inputCompletion.gif │ ├── log-diagnostic.gif │ ├── runAfter.gif │ ├── start-pipeline.gif │ ├── taskRef.gif │ ├── tekton-logo.png │ └── tektonHub.gif ├── openapitools.json ├── package-lock.json ├── package.json ├── pipeline-examples ├── Task.yml ├── TaskRun.yml └── output-pipelinerun.yaml ├── rawsnippets ├── EventListener.yaml ├── cluster-triggerbinding.yaml ├── clustertask.yaml ├── condition.yaml ├── k8s-limits.yaml ├── pipeline-condition.yaml ├── pipeline-finally.yaml ├── pipeline-with-multiple-task.yaml ├── pipeline.yaml ├── pipelineResource.yaml ├── pipelineResourceType.yaml ├── pipelineTaskCondition.yaml ├── pipelineTaskReference.yaml ├── pipelineTaskReferenceInputs.yaml ├── pipelinerun.yaml ├── task.yaml ├── taskinput.yaml ├── taskrun.yaml ├── tektonParameter.yaml ├── tektonTaskParameter.yaml ├── tektonTaskStep.yaml ├── triggerbinding.yaml └── triggertemplate.yaml ├── scheme ├── index.properties ├── tekton.dev │ ├── v1_Pipeline.json │ ├── v1_PipelineList.json │ ├── v1_PipelineRun.json │ ├── v1_PipelineRunList.json │ ├── v1_Task.json │ ├── v1_TaskList.json │ ├── v1_TaskRun.json │ ├── v1_TaskRunList.json │ ├── v1alpha1_ClusterTask.json │ ├── v1alpha1_ClusterTaskList.json │ ├── v1alpha1_Condition.json │ ├── v1alpha1_ConditionList.json │ ├── v1alpha1_Pipeline.json │ ├── v1alpha1_PipelineList.json │ ├── v1alpha1_PipelineResource.json │ ├── v1alpha1_PipelineResourceList.json │ ├── v1alpha1_PipelineRun.json │ ├── v1alpha1_PipelineRunList.json │ ├── v1alpha1_Task.json │ ├── v1alpha1_TaskList.json │ ├── v1alpha1_TaskRun.json │ ├── v1alpha1_TaskRunList.json │ ├── v1beta1_ClusterTask.json │ ├── v1beta1_ClusterTaskList.json │ ├── v1beta1_Pipeline.json │ ├── v1beta1_PipelineList.json │ ├── v1beta1_PipelineRun.json │ ├── v1beta1_PipelineRunList.json │ ├── v1beta1_Task.json │ ├── v1beta1_TaskList.json │ ├── v1beta1_TaskRun.json │ └── v1beta1_TaskRunList.json └── triggers.tekton.dev │ ├── v1alpha1_ClusterInterceptor.json │ ├── v1alpha1_ClusterInterceptorList.json │ ├── v1alpha1_ClusterTriggerBinding.json │ ├── v1alpha1_ClusterTriggerBindingList.json │ ├── v1alpha1_EventListener.json │ ├── v1alpha1_EventListenerList.json │ ├── v1alpha1_Trigger.json │ ├── v1alpha1_TriggerBinding.json │ ├── v1alpha1_TriggerBindingList.json │ ├── v1alpha1_TriggerList.json │ ├── v1alpha1_TriggerTemplate.json │ ├── v1alpha1_TriggerTemplateList.json │ ├── v1beta1_ClusterTriggerBinding.json │ ├── v1beta1_ClusterTriggerBindingList.json │ ├── v1beta1_EventListener.json │ ├── v1beta1_EventListenerList.json │ ├── v1beta1_Trigger.json │ ├── v1beta1_TriggerBinding.json │ ├── v1beta1_TriggerBindingList.json │ ├── v1beta1_TriggerList.json │ ├── v1beta1_TriggerTemplate.json │ └── v1beta1_TriggerTemplateList.json ├── snippets └── tekton.json ├── src ├── check-cluster.ts ├── cli-command.ts ├── cli.ts ├── cluster-version.ts ├── commands.ts ├── commands │ ├── common.ts │ └── delete.ts ├── constants.ts ├── context-type.ts ├── debugger │ ├── cancel-taskrun.ts │ ├── debug-continue.ts │ ├── debug-fail-continue.ts │ ├── debug-tree-view.ts │ ├── debug.ts │ ├── debugExplorer.ts │ ├── delete-debugger.ts │ └── show-in-terminal.ts ├── extension.ts ├── hub │ ├── hub-client.ts │ ├── hub-common.ts │ ├── hub-recommendation.ts │ ├── hub-view.ts │ ├── install-resource.ts │ ├── task-page-manager.ts │ ├── task-page-view.ts │ └── uninstall-task.ts ├── humanizer.ts ├── icon-path.ts ├── kubectl.ts ├── kubernetes.ts ├── model │ ├── common.ts │ ├── document.ts │ ├── element-type.ts │ └── pipeline │ │ ├── pipeline-model.ts │ │ └── task-model.ts ├── pipeline │ ├── bundle.ts │ ├── customTektonExplorer.ts │ ├── pipeline-graph.ts │ ├── pipeline-preview.ts │ ├── pipelineExplorer.ts │ ├── preview-manager.ts │ ├── preview.ts │ └── wizard.ts ├── project-analizer │ ├── language-recongnizer │ │ └── recognazer.ts │ └── project-types.ts ├── tekton-hub-client │ ├── .openapi-generator-ignore │ ├── api.ts │ ├── base.ts │ ├── configuration.ts │ └── index.ts ├── tekton.d.ts ├── tekton │ ├── addtrigger.ts │ ├── bundle-pipeline-task.ts │ ├── clustertask.ts │ ├── clustertriggerbunding.ts │ ├── collect-data-for-wizard.ts │ ├── condition.ts │ ├── create-resources.ts │ ├── create-wizard-for-task-or-clustertask.ts │ ├── deploy.ts │ ├── diagnostic.ts │ ├── eventlistener.ts │ ├── expose.ts │ ├── generate-template.ts │ ├── k8s-type.ts │ ├── pipeline.ts │ ├── pipelineresource.ts │ ├── pipelinerun.ts │ ├── restartpipelinerundata.ts │ ├── start-pipeline-from-json.ts │ ├── start-task-or-clustertask-from-yaml.ts │ ├── task-run-data.ts │ ├── task.ts │ ├── taskrun.ts │ ├── tektonitem.ts │ ├── trigger.ts │ ├── triggerbinding.ts │ ├── triggertemplate.ts │ └── triggertype.ts ├── telemetry.ts ├── tkn.ts ├── tools.json ├── tools.ts ├── tree-view │ ├── conditon-node.ts │ ├── debug-node.ts │ ├── expand-node.ts │ ├── pipelinerun-node.ts │ ├── task-run-node.ts │ ├── taskrun-for-pipeline-node.ts │ └── tekton-node.ts ├── util │ ├── MultiStepInput.ts │ ├── archive.ts │ ├── check-cluster-status.ts │ ├── check-ref-resource.ts │ ├── create-resource-spec.ts │ ├── detection.ts │ ├── disposable.ts │ ├── download.ts │ ├── exposeurl.ts │ ├── filename.ts │ ├── hideclusterinformation.ts │ ├── list-tekton-resource.ts │ ├── log-in-editor.ts │ ├── map-object.ts │ ├── platform.ts │ ├── progress.ts │ ├── resource-kind.ts │ ├── stderrstring.ts │ ├── tekton-vfs.ts │ ├── telemetry-watch-tekton-resource.ts │ ├── tknversion.ts │ ├── watch.ts │ ├── watchResources.ts │ └── windowUtils.ts ├── webview │ ├── bundle │ │ ├── App.tsx │ │ ├── Form.tsx │ │ ├── bundle.style.tsx │ │ ├── form-components │ │ │ ├── FormInputProps.ts │ │ │ ├── FormInputText.tsx │ │ │ ├── SelectAllTransferList.tsx │ │ │ └── customChip.tsx │ │ ├── index.css │ │ ├── index.tsx │ │ └── style.scss │ ├── common │ │ ├── dom-util.ts │ │ ├── list-widget.ts │ │ ├── list.css │ │ ├── loader.css │ │ ├── loader.ts │ │ ├── reset.css │ │ ├── vscode-api.ts │ │ ├── vscode.css │ │ └── widget.ts │ ├── hub │ │ ├── custom.d.ts │ │ ├── hub.css │ │ ├── index.ts │ │ ├── pipeline.svg │ │ ├── resource-view.ts │ │ ├── search_dropdown.ts │ │ └── task.svg │ ├── pipeline-preview │ │ ├── index.ts │ │ ├── model.ts │ │ ├── popup.css │ │ └── task-popup.ts │ ├── pipeline │ │ └── app │ │ │ ├── editor.ts │ │ │ ├── index.ts │ │ │ ├── style.css │ │ │ ├── utils │ │ │ ├── const.ts │ │ │ ├── disablebutton.ts │ │ │ ├── displayworkspaceresource.ts │ │ │ ├── item.ts │ │ │ ├── resource.ts │ │ │ ├── types.ts │ │ │ └── util.ts │ │ │ └── widgets │ │ │ ├── buttonspanel.ts │ │ │ ├── inputwidget.ts │ │ │ ├── maincontent.ts │ │ │ ├── navigation.ts │ │ │ └── selectwidget.ts │ └── resource-page │ │ ├── index.ts │ │ ├── resource-widget.ts │ │ ├── task.css │ │ └── yaml-highlight.css └── yaml-support │ ├── snippet.ts │ ├── tkn-code-actions.ts │ ├── tkn-completion-item-provider.ts │ ├── tkn-definition-providers.ts │ ├── tkn-editing.ts │ ├── tkn-scheme-storage.ts │ ├── tkn-tasks-provider.ts │ ├── tkn-yaml-schema.ts │ ├── tkn-yaml-scheme-generator.ts │ ├── tkn-yaml.ts │ └── yaml-locator.ts ├── test ├── cli.test.ts ├── coverage.ts ├── debugger │ ├── cancel-taskrun.test.ts │ ├── debug-continue.test.ts │ ├── debug-fail-continue.test.ts │ ├── debug.test.ts │ ├── debugExplorer.test.ts │ └── show-in-terminal.test.ts ├── explorer.test.ts ├── extension.test.ts ├── fixtures │ ├── test.gz │ ├── test.tar.gz │ └── test.zip ├── hub │ └── install-task.test.ts ├── index.ts ├── kubernetes.test.ts ├── model │ └── pipeline │ │ ├── pipeline-model.test.ts │ │ ├── pipeline-with-finally.yaml │ │ └── pipeline.yaml ├── pipeline │ ├── custom-tekton-explorer.test.ts │ ├── pipeline-graph.test.ts │ └── pipeline-preview.test.ts ├── pipelinerun.json ├── single-test-run.ts ├── tekton │ ├── addtrigger.test.ts │ ├── clustertask.test.ts │ ├── create-resources.test.ts │ ├── deploy.test.ts │ ├── diagnostic.test.ts │ ├── expose.test.ts │ ├── generate-template.test.ts │ ├── pipeline.test.ts │ ├── pipelineresource.test.ts │ ├── pipelinerun.test.ts │ ├── start-pipeline-from-json.test.ts │ ├── start-task-or-clustertask-from-yaml.test.ts │ ├── task.test.ts │ ├── taskrun.test.ts │ ├── tektonitem.test.ts │ ├── testTektonitem.ts │ ├── trigger.test.ts │ └── triggertemplate.test.ts ├── text-document-mock.ts ├── tkn.int.ts ├── tkn.test.ts ├── tools.test.ts ├── util │ ├── archive.test.ts │ ├── check-ref-resource.test.ts │ ├── download.test.ts │ ├── hideclusterinformation.test.ts │ ├── platform.test.ts │ ├── progress.test.ts │ ├── tekton-vfs.test.ts │ ├── watch.test.ts │ └── window.test.ts └── yaml-support │ ├── conditional-pipeline.yaml │ ├── echo-hello-task.yaml │ ├── extract-task-pipeline.yaml │ ├── multitype.yaml │ ├── pipeline-ordering.yaml │ ├── pipelinerun.yaml │ ├── scheme-storage.test.ts │ ├── tasks-provider.test.ts │ ├── tkn-code-actions.test.ts │ ├── tkn-editing.test.ts │ ├── tkn-yaml-scheme-generator.test.ts │ └── tkn-yaml.test.ts ├── tsconfig.json ├── ui-test ├── all.ts ├── common │ ├── conditions.ts │ ├── constants.ts │ └── utils.ts ├── public-suite │ ├── all-public.ts │ ├── command-palette-test.ts │ ├── extension-activity-test.ts │ └── extension-view-test.ts ├── resources │ └── simple-task.yaml └── suite │ ├── dummy-test.ts │ ├── task-test.ts │ └── tekton-view-test.ts ├── webpack.config.js └── webview-tsconfig.json /.eslintignore: -------------------------------------------------------------------------------- 1 | # don't ever lint node_modules 2 | node_modules 3 | # don't lint build output 4 | out 5 | # don't lint nyc coverage output 6 | coverage 7 | 8 | preview 9 | 10 | src/tekton-hub-client/ 11 | 12 | test-resources 13 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: '@typescript-eslint/parser', 4 | env: { 5 | node: true 6 | }, 7 | parserOptions: { 8 | 'sourceType': 'module', 9 | }, 10 | plugins: [ 11 | '@typescript-eslint', 12 | 'header', 13 | ], 14 | extends: [ 15 | 'eslint:recommended', 16 | 'plugin:@typescript-eslint/eslint-recommended', 17 | 'plugin:@typescript-eslint/recommended', 18 | ], 19 | rules: { 20 | 'header/header': [2, './header.js'], 21 | '@typescript-eslint/no-use-before-define': ['error', { 'functions': false, 'classes': false }], 22 | '@typescript-eslint/no-unused-vars': [1], 23 | '@typescript-eslint/explicit-function-return-type': [1, { 'allowExpressions': true }], 24 | 'indent': ['error', 2, { 'SwitchCase': 1 }], 25 | 'quotes': ['error', 'single'], 26 | 'eol-last': ['error'], 27 | 'space-infix-ops': ['error', { 'int32Hint': false }], 28 | 'no-multi-spaces': ['error', { "ignoreEOLComments": true }], 29 | 'keyword-spacing': ['error'], 30 | "@typescript-eslint/no-namespace": "off" 31 | }, 32 | 33 | }; 34 | -------------------------------------------------------------------------------- /.github/workflows/ci-workflow.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow 2 | 3 | name: CI 4 | 5 | # Controls when the action will run. Triggers the workflow on push or pull request 6 | # events but only for the main branch 7 | on: 8 | push: 9 | branches: [main] 10 | pull_request: 11 | branches: [main] 12 | 13 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 14 | jobs: 15 | # This workflow contains a single job called "build" 16 | build: 17 | # The type of runner that the job will run on 18 | runs-on: ${{ matrix.os }} 19 | strategy: 20 | matrix: 21 | os: [macos-latest, windows-latest, ubuntu-latest] 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v2 27 | with: 28 | fetch-depth: 0 29 | 30 | # Set up Node 31 | - name: Use Node 16.x 32 | uses: actions/setup-node@v1 33 | with: 34 | node-version: 16.11.0 35 | 36 | # Run install dependencies 37 | - name: Install dependencies 38 | run: npm i 39 | 40 | # Build extension 41 | - name: Run prepublish 42 | run: npm run vscode:prepublish 43 | 44 | # Run tests 45 | - name: Run Tests 46 | uses: GabrielBB/xvfb-action@v1.0 47 | with: 48 | run: npm test --silent 49 | 50 | # Run UI tests 51 | - name: Run UI Tests 52 | uses: GabrielBB/xvfb-action@v1.6 53 | with: 54 | run: npm run public-ui-test 55 | options: -screen 0 1920x1080x24 56 | 57 | # Archiving integration tests artifacts 58 | - name: Upload test artifacts 59 | uses: actions/upload-artifact@v2 60 | if: failure() 61 | with: 62 | name: artifacts-${{ matrix.os }} 63 | path: | 64 | test-resources/screenshots/*.png 65 | retention-days: 2 66 | 67 | # Upload coverage to codecov.io 68 | - name: Codecov 69 | uses: codecov/codecov-action@v1.0.12 70 | if: runner.os == 'Linux' 71 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | .vscode-test/ 4 | *.vsix 5 | coverage/ 6 | preview/ 7 | .DS_Store 8 | test-resources 9 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dbaeumer.vscode-eslint", 6 | "eg2.vscode-npm-script", 7 | "ryanluker.vscode-coverage-gutters", 8 | "streetsidesoftware.code-spell-checker" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false, // set this to true to hide the "out" folder with the compiled JS files 5 | "test-resources": true 6 | }, 7 | "search.exclude": { 8 | "out": true, // set this to false to include "out" folder in search results 9 | "test-resources": true 10 | }, 11 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 12 | "typescript.tsc.autoDetect": "off", 13 | "debug.node.autoAttach": "off", 14 | "svg.preview.background": "white", 15 | // Run ESlint after every save action 16 | "editor.codeActionsOnSave": { 17 | "source.fixAll.eslint": true 18 | }, 19 | "eslint.validate": [ 20 | "typescript" 21 | ], 22 | "cSpell.words": [ 23 | "tekton" 24 | ] 25 | 26 | } 27 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | out/**/*.map 5 | src/** 6 | .gitignore 7 | tsconfig.json 8 | vsc-extension-quickstart.md 9 | tslint.json 10 | *.vsix 11 | test/** 12 | coverage/** 13 | coverconfig.json 14 | Jenkinsfile 15 | .gitattributes 16 | .travis.yml 17 | CONTRIBUTING.md 18 | test-resources -------------------------------------------------------------------------------- /DCO: -------------------------------------------------------------------------------- 1 | Developer Certificate of Origin 2 | Version 1.1 3 | 4 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 5 | 1 Letterman Drive 6 | Suite D4700 7 | San Francisco, CA, 94129 8 | 9 | Everyone is permitted to copy and distribute verbatim copies of this 10 | license document, but changing it is not allowed. 11 | 12 | 13 | Developer's Certificate of Origin 1.1 14 | 15 | By making a contribution to this project, I certify that: 16 | 17 | (a) The contribution was created in whole or in part by me and I 18 | have the right to submit it under the open source license 19 | indicated in the file; or 20 | 21 | (b) The contribution is based upon previous work that, to the best 22 | of my knowledge, is covered under an appropriate open source 23 | license and I have the right under that license to submit that 24 | work with modifications, whether created in whole or in part 25 | by me, under the same open source license (unless I am 26 | permitted to submit under a different license), as indicated 27 | in the file; or 28 | 29 | (c) The contribution was provided directly to me by some other 30 | person who certified (a), (b) or (c) and I have not modified 31 | it. 32 | 33 | (d) I understand and agree that this project and the contribution 34 | are public and that a record of the contribution (including all 35 | personal information I submit with it, including my sign-off) is 36 | maintained indefinitely and may be redistributed consistent with 37 | this project or the open source license(s) involved. 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Red Hat. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /TUTORIAL.md: -------------------------------------------------------------------------------- 1 | # Tekton Pipelines Extension Tutorial 2 | 3 | This tutorial goal is to let you go through all the steps in original 4 | [OpenShift Pipelines Tutorial](https://github.com/openshift/pipelines-tutorial/#install-openshift-pipelines) 5 | without leaving Visual Studio Code window. 6 | 7 | ## Requirements 8 | 9 | The tutorial assumes you have: 10 | * An access to remote or local OpenShift cluster. 11 | * Tekton deployed on your OpenShift cluster. 12 | * Visual Studio Code installed. 13 | 14 | ## Configure Visual Studio Code and Install Required Extensions 15 | 16 | For this tutorial you need to install required extensions from Visual Studio Code Marketplace: 17 | * Tekton Pipelines - https://marketplace.visualstudio.com/items?itemName=redhat.vscode-tekton-pipelines 18 | * OpenShift Connector - https://marketplace.visualstudio.com/items?itemName=redhat.vscode-openshift-connector 19 | 20 | ## OpenShift and Tekton Task Catalogs Git Repositories 21 | 22 | Tekton Pipeline extension does not provide integration with task catalogs yet. To create tekton tasks used 23 | in this tutorial you are going to use two github repositories: 24 | * Tekton Tasks catalog - https://github.com/tektoncd/catalog 25 | * OpenShift Pipelines catalog - https://github.com/openshift/pipelines-catalog 26 | 27 | ### Pipelines Tutorial Git Repository 28 | 29 | You will use resources from original tutorial repository to deploy your application on the cluster: 30 | * OpenShift Pipeline Tutorial - https://github.com/openshift/pipelines-tutorial 31 | * Tekton Pipelines Tutorial - https://github.com/tektoncd/pipeline/blob/master/docs/tutorial.md 32 | 33 | ## Demo Video 34 | 35 | [![](http://img.youtube.com/vi/gte70CuQXbM/0.jpg)](http://www.youtube.com/watch?v=gte70CuQXbM "") 36 | 37 | -------------------------------------------------------------------------------- /USAGE_DATA.md: -------------------------------------------------------------------------------- 1 | ## [Tekton Pipelines](https://github.com/redhat-developer/vscode-tekton) 2 | 3 | ### Usage Data 4 | 5 | * when extension is activated 6 | * when a command contributed by extension is executed 7 | * command's ID 8 | * command's error message (in case of exception) 9 | * command's specific data like tkn, kubectl version and to check which command user has used. 10 | * when extension is deactivated 11 | * Watch on all tekton resources. 12 | * Command which send data to telemetry. 13 | * About command. 14 | * Open Pipeline preview to the side command. 15 | * Show output channel command. 16 | * Refresh command. 17 | * Start pipeline from k8s command. 18 | * Start task from k8s command. 19 | * Start pipeline command. 20 | * Add trigger command. 21 | * Start pipeline from command palette. 22 | * OpenInEditor command. 23 | * Start last pipeline run command. 24 | * Delete command. 25 | * Restart pipelineRun command. 26 | * Show diagnostic data command. 27 | * Restart taskRun command. 28 | * Copy expose url command. 29 | * start task command. 30 | * start task command from palette. 31 | * Report issue command. 32 | * Refresh view command. 33 | * Remove selected command. 34 | * Open condition definition command. 35 | * Open task definition command. 36 | * Generate TaskRun template command. 37 | * Tekton hub. 38 | * Collect OpenShift and kubernetes cluster version. 39 | 40 | -------------------------------------------------------------------------------- /build/build-svg-icons.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | import * as path from 'path'; 6 | import * as fs from 'fs-extra'; 7 | import * as svgTools from 'simple-svg-tools'; 8 | import { exit } from 'shelljs'; 9 | 10 | const icons = ['C.svg', 'TR.svg', 'PLR.svg']; 11 | const stateToColor = { 12 | error: 'red', 13 | pending: 'grey' 14 | }; 15 | 16 | const imagesPath = path.join(__dirname, '..', '..', 'images'); 17 | const destinationPath = path.join(__dirname, '..', '..', 'images', 'generated'); 18 | fs.ensureDirSync(destinationPath); 19 | 20 | 21 | async function generateIcons(): Promise { 22 | for (const icon of icons) { 23 | const iconPath = path.join(imagesPath, icon); 24 | if (fs.existsSync(iconPath)) { 25 | 26 | for (const state in stateToColor) { 27 | const color = stateToColor[state]; 28 | fs.ensureDirSync(path.join(destinationPath, state)); 29 | let svg = await svgTools.ImportSVG(iconPath); 30 | svg = await svgTools.SVGO(svg); 31 | svg = await svgTools.ChangePalette(svg, { 32 | '#38812f': color, 33 | }); 34 | 35 | await svgTools.ExportSVG(svg, path.join(destinationPath, state, icon)); 36 | } 37 | } 38 | } 39 | } 40 | 41 | generateIcons().then(() => exit(0)); 42 | -------------------------------------------------------------------------------- /build/install-vscode.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import cp = require('child_process'); 7 | import path = require('path'); 8 | import { platform } from 'os'; 9 | // eslint-disable-next-line @typescript-eslint/no-var-requires 10 | const downloadAndUnzipVSCode = require('vscode-test').downloadAndUnzipVSCode; 11 | downloadAndUnzipVSCode().then((executable: string) => { 12 | if (platform() === 'darwin') { 13 | executable = `'${path.join(executable.substring(0, executable.indexOf('.app') + 4), 'Contents', 'Resources', 'app', 'bin', 'code')}'`; 14 | } else { 15 | executable = path.join(path.dirname(executable), 'bin', 'code'); 16 | } 17 | const dependencies = ['redhat.vscode-yaml']; 18 | for (const dep of dependencies) { 19 | const installLog = cp.execSync(`${executable} --install-extension ${dep}`); 20 | console.log(installLog.toString()); 21 | } 22 | }); 23 | -------------------------------------------------------------------------------- /build/unit-tests.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import * as path from 'path'; 7 | 8 | import { runTests } from 'vscode-test'; 9 | 10 | async function main(): Promise { 11 | try { 12 | // The folder containing the Extension Manifest package.json 13 | // Passed to `--extensionDevelopmentPath` 14 | const extensionDevelopmentPath = path.resolve(__dirname, '../../'); 15 | 16 | // The path to the extension test runner script 17 | // Passed to --extensionTestsPath 18 | const extensionTestsPath = path.resolve(__dirname, '../../out/test/'); 19 | 20 | // Download VS Code, unzip it and run the integration test 21 | console.log(extensionDevelopmentPath, extensionTestsPath); 22 | await runTests({ 23 | extensionDevelopmentPath, extensionTestsPath, 24 | launchArgs: [ 25 | // This disables all extensions except the one being testing 26 | // '--disable-extensions', 27 | // '--verbose', 28 | ], 29 | }); 30 | } catch (err) { 31 | console.error(err); 32 | process.exit(1); 33 | } 34 | } 35 | 36 | main(); 37 | -------------------------------------------------------------------------------- /build/verify-tools.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | 'use strict'; 7 | 8 | import hasha = require('hasha'); 9 | import mkdirp = require('mkdirp'); 10 | import fs = require('fs-extra'); 11 | import path = require('path'); 12 | import cp = require('child_process'); 13 | import configData = require('../src/tools.json'); 14 | import os = require('os'); 15 | import { DownloadUtil } from '../src/util/download'; 16 | 17 | async function downloadFileAndCreateSha256(targetFolder: string, fileName: string, reqURL: string, sha256sum: string): Promise { 18 | if (!fs.existsSync(targetFolder)) { 19 | await mkdirp.sync(targetFolder); 20 | } 21 | const currentFile = path.join(targetFolder, fileName); 22 | console.log(`${currentFile} download started from ${reqURL}`); 23 | await DownloadUtil.downloadFile(reqURL, currentFile, (current) => console.log(current + '%')); 24 | const currentSHA256 = await hasha.fromFile(currentFile, { algorithm: 'sha256' }); 25 | if (currentSHA256 === sha256sum) { 26 | console.log(`[INFO] ${currentFile} is downloaded and sha256 is correct`); 27 | } else { 28 | throw Error(`${currentFile} is downloaded and sha256 is not correct`); 29 | } 30 | } 31 | 32 | async function verifyTools(): Promise { 33 | for (const key in configData) { 34 | for (const OS in configData[key].platform) { 35 | const targetFolder = path.resolve(os.tmpdir(), OS); 36 | await downloadFileAndCreateSha256(targetFolder, configData[key].platform[OS].dlFileName, configData[key].platform[OS].url, configData[key].platform[OS].sha256sum); 37 | } 38 | } 39 | } 40 | 41 | const fileCheckRegex = /\w*tools.json/; 42 | cp.exec('git diff --name-only origin/main -- .', async (error, stdout) => { 43 | if (error) { 44 | throw error; 45 | } 46 | console.log('The changed files:'); 47 | console.log(stdout); 48 | if (fileCheckRegex.test(stdout)) { 49 | console.log('tools.json is changed, starting download verification'); 50 | await verifyTools(); 51 | } else { 52 | console.log('tools.json is not changed, skipping download verification'); 53 | } 54 | }); 55 | -------------------------------------------------------------------------------- /coverconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "relativeSourcePath": "../src", 3 | "relativeCoverageDir": "../../coverage", 4 | "ignorePatterns": [ 5 | "**/node_modules/**" 6 | ], 7 | "includePid": false, 8 | "reports": [ 9 | "html", 10 | "text", 11 | "cobertura", 12 | "json", 13 | "lcov" 14 | ], 15 | "verbose": false 16 | } 17 | -------------------------------------------------------------------------------- /header.js: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | -------------------------------------------------------------------------------- /images/C.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/CT.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/CTB.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/EL.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/PL.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/PLR.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/PR.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 10 | 11 | 15 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /images/T.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/TB.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/TR.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /images/TT.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/cancelled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/cancelled.png -------------------------------------------------------------------------------- /images/dark/build.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /images/dark/debug-alt-small.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /images/dark/debug-continue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /images/dark/debug-stop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /images/dark/go-to-file.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /images/dark/go-to-task.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /images/dark/icon-close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /images/dark/icon-delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /images/dark/icon-diagram.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | background 5 | 6 | 7 | 8 | Layer 1 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /images/dark/icon-focus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /images/dark/icon-refresh.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /images/dark/icon-reset.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/dark/preview-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /images/dark/versions.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /images/debug-alt-small.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /images/debug-continue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /images/debug-pause.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /images/debug-stop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /images/generated/error/C.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/generated/error/PLR.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/generated/error/TR.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/generated/pending/C.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/generated/pending/PLR.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/generated/pending/TR.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/gif-tekton/add-trigger.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/gif-tekton/add-trigger.gif -------------------------------------------------------------------------------- /images/gif-tekton/auto-refresh.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/gif-tekton/auto-refresh.gif -------------------------------------------------------------------------------- /images/gif-tekton/code-completion.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/gif-tekton/code-completion.gif -------------------------------------------------------------------------------- /images/gif-tekton/create-pvc-workspaces.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/gif-tekton/create-pvc-workspaces.gif -------------------------------------------------------------------------------- /images/gif-tekton/create-workspace-pvc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/gif-tekton/create-workspace-pvc.gif -------------------------------------------------------------------------------- /images/gif-tekton/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/gif-tekton/demo.gif -------------------------------------------------------------------------------- /images/gif-tekton/deploy-resource.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/gif-tekton/deploy-resource.gif -------------------------------------------------------------------------------- /images/gif-tekton/go-to-defination.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/gif-tekton/go-to-defination.gif -------------------------------------------------------------------------------- /images/gif-tekton/pipeline-diagram.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/gif-tekton/pipeline-diagram.gif -------------------------------------------------------------------------------- /images/gif-tekton/restart-pipeline.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/gif-tekton/restart-pipeline.gif -------------------------------------------------------------------------------- /images/gif-tekton/show-logs-in-editor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/gif-tekton/show-logs-in-editor.gif -------------------------------------------------------------------------------- /images/gif-tekton/start-pipeline.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/gif-tekton/start-pipeline.gif -------------------------------------------------------------------------------- /images/gif-tekton/start-workspaces.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/gif-tekton/start-workspaces.gif -------------------------------------------------------------------------------- /images/gif-tekton/tekton-hub-cluster.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/gif-tekton/tekton-hub-cluster.gif -------------------------------------------------------------------------------- /images/gif-tekton/tekton-hub.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/gif-tekton/tekton-hub.gif -------------------------------------------------------------------------------- /images/light/build.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /images/light/debug-pause.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /images/light/go-to-file.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /images/light/go-to-task.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /images/light/icon-close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /images/light/icon-delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /images/light/icon-diagram.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | background 5 | 6 | 7 | 8 | Layer 1 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /images/light/icon-focus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /images/light/icon-refresh.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /images/light/icon-reset.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/light/preview-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /images/light/versions.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /images/pending.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/running.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/running.gif -------------------------------------------------------------------------------- /images/tekton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/tekton.png -------------------------------------------------------------------------------- /images/tkn-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/tkn-down.png -------------------------------------------------------------------------------- /images/walkthrough/create-resource.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/walkthrough/create-resource.gif -------------------------------------------------------------------------------- /images/walkthrough/debug.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/walkthrough/debug.gif -------------------------------------------------------------------------------- /images/walkthrough/inputCompletion.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/walkthrough/inputCompletion.gif -------------------------------------------------------------------------------- /images/walkthrough/log-diagnostic.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/walkthrough/log-diagnostic.gif -------------------------------------------------------------------------------- /images/walkthrough/runAfter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/walkthrough/runAfter.gif -------------------------------------------------------------------------------- /images/walkthrough/start-pipeline.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/walkthrough/start-pipeline.gif -------------------------------------------------------------------------------- /images/walkthrough/taskRef.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/walkthrough/taskRef.gif -------------------------------------------------------------------------------- /images/walkthrough/tekton-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/walkthrough/tekton-logo.png -------------------------------------------------------------------------------- /images/walkthrough/tektonHub.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/images/walkthrough/tektonHub.gif -------------------------------------------------------------------------------- /openapitools.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", 3 | "spaces": 2, 4 | "generator-cli": { 5 | "version": "4.3.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /pipeline-examples/Task.yml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1alpha1 2 | kind: Task 3 | metadata: 4 | name: echo-hello-world 5 | spec: 6 | steps: 7 | - name: echo 8 | image: ubuntu 9 | command: 10 | - echo 11 | args: 12 | - "hello world" 13 | -------------------------------------------------------------------------------- /pipeline-examples/TaskRun.yml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1alpha1 2 | kind: TaskRun 3 | metadata: 4 | name: echo-hello-world-task-run 5 | spec: 6 | taskRef: 7 | name: echo-hello-world 8 | trigger: 9 | type: manual 10 | -------------------------------------------------------------------------------- /rawsnippets/EventListener.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: triggers.tekton.dev/v1beta1 2 | kind: EventListener 3 | metadata: 4 | name: ${1:name} 5 | spec: 6 | serviceAccountName: ${2:serviceAccount} 7 | triggers: 8 | - name: ${3:triggerName} 9 | bindings: 10 | - name: ${4:bindingName} 11 | template: 12 | name: ${5:templateName} 13 | -------------------------------------------------------------------------------- /rawsnippets/cluster-triggerbinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: triggers.tekton.dev/v1beta1 2 | kind: ClusterTriggerBinding 3 | metadata: 4 | name: ${1:name} 5 | spec: 6 | params: 7 | - name: ${2:param_name} 8 | value: ${3:value} 9 | -------------------------------------------------------------------------------- /rawsnippets/clustertask.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: ClusterTask 3 | metadata: 4 | name: ${1:foo} 5 | spec: 6 | steps: 7 | - image: ${2:alpine} 8 | script: ${3:echo hello} 9 | -------------------------------------------------------------------------------- /rawsnippets/condition.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1alpha1 2 | kind: Condition 3 | metadata: 4 | name: ${1:foo} 5 | spec: 6 | check: 7 | image: ${2:alpine} 8 | script: ${3:echo hello} 9 | -------------------------------------------------------------------------------- /rawsnippets/k8s-limits.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | limits: 3 | cpu: 4 4 | memory: 6Gi 5 | requests: 6 | cpu: 2 7 | memory: 4Gi -------------------------------------------------------------------------------- /rawsnippets/pipeline-condition.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: ${1:app-deploy} 5 | spec: 6 | tasks: 7 | - name: ${2:taskName} 8 | taskRef: 9 | name: ${3:taskRefName} 10 | conditions: 11 | - conditionRef: ${4:conditionRefName} 12 | -------------------------------------------------------------------------------- /rawsnippets/pipeline-finally.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: ${1:app-deploy} 5 | spec: 6 | tasks: 7 | - name: ${2:taskName} 8 | taskRef: 9 | name: ${3:build-app} 10 | finally: 11 | - name: ${4:finallyName} 12 | taskRef: 13 | name: ${5:taskName} 14 | -------------------------------------------------------------------------------- /rawsnippets/pipeline-with-multiple-task.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: ${1:app-deploy} 5 | spec: 6 | workspaces: 7 | - name: ${2:maven-settings} 8 | - name: ${3:my-source} 9 | tasks: 10 | - name: ${4:taskName} 11 | taskRef: 12 | name: ${5:maven} 13 | params: 14 | - name: ${6:CONTEXT_DIR} 15 | value: ${7:"apps/greeter/java/quarkus"} #configure: may change according to your source 16 | - name: ${8:GOALS} 17 | value: ${9:["package"]} 18 | workspaces: 19 | - name: ${10:maven-settings} 20 | workspace: ${11:maven-settings} 21 | - name: ${12:taskName} 22 | taskRef: 23 | name: ${13:buildah} 24 | params: 25 | - name: ${14:IMAGE} 26 | value: ${15:gcr.io/my-repo/my-image} #configure: may change according to your source 27 | workspaces: 28 | - name: ${16:source} 29 | workspace: ${17:my-source} 30 | - name: ${18:taskName} 31 | taskRef: 32 | name: ${19:kubectl-deploy-pod} 33 | params: 34 | - name: ${20:action} 35 | value: ${21:create} #configure: may change according to your source 36 | - name: ${22:success-condition} 37 | value: ${23:status.phase == Running} 38 | - name: ${24:failure-condition} 39 | value: ${25:status.phase in (Failed, Error)} 40 | - name: ${26:output} 41 | value: | 42 | - name: ${27:job-name} 43 | valueFrom: ${28:'{.metadata.name}'} 44 | - name: ${29:job-namespace} 45 | valueFrom: ${30:'{.metadata.namespace}'} 46 | - name: ${31:set-ownerreference} 47 | value: ${32:"true"} 48 | - name: ${33:manifest} 49 | value: | 50 | apiVersion: ${34:v1} 51 | kind: ${35:Pod} 52 | metadata: 53 | generateName: ${36:myapp-pod-} 54 | labels: 55 | app: ${37:myapp} 56 | spec: 57 | containers: 58 | - name: ${38:myapp-container} 59 | image: ${39:docker} 60 | command: ${40:['sh', '-c', 'echo Hello Kubernetes! && sleep 30']} 61 | -------------------------------------------------------------------------------- /rawsnippets/pipeline.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: 2 | kind: Pipeline 3 | metadata: 4 | name: ${1:app-deploy} 5 | spec: 6 | resources: 7 | - name: ${2:pipeline-resource-type} 8 | type: ${3:pipeline-type} 9 | tasks: 10 | - name: ${4:taskName} 11 | taskRef: 12 | name: ${5:build-app} 13 | -------------------------------------------------------------------------------- /rawsnippets/pipelineResource.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1alpha1 2 | kind: PipelineResource 3 | metadata: 4 | name: ${1:git-source} 5 | spec: 6 | type: ${2|git,image,pullRequest,cluster,storage,gcs,build-gcs,cloudevent|} 7 | $LINE_COMMENT params: 8 | $LINE_COMMENT Check https://github.com/tektoncd/pipeline/blob/master/docs/resources.md#pipelineresources for more applicable parameters 9 | -------------------------------------------------------------------------------- /rawsnippets/pipelineResourceType.yaml: -------------------------------------------------------------------------------- 1 | - name: ${1:app-source} 2 | type: ${2|git,image,pullRequest,cluster,storage,gcs,build-gcs,cloudevent|} 3 | -------------------------------------------------------------------------------- /rawsnippets/pipelineTaskCondition.yaml: -------------------------------------------------------------------------------- 1 | conditions: 2 | - conditionRef: ${1:conditionName} 3 | params: 4 | - name: ${2:path} 5 | value: ${3:$(params.path)} 6 | -------------------------------------------------------------------------------- /rawsnippets/pipelineTaskReference.yaml: -------------------------------------------------------------------------------- 1 | - name: ${1:taskName} 2 | taskRef: 3 | name: ${2:build-and-push} 4 | runAfter: 5 | - ${3:another-task-name} 6 | $LINE_COMMENT params: 7 | $LINE_COMMENT resources: 8 | -------------------------------------------------------------------------------- /rawsnippets/pipelineTaskReferenceInputs.yaml: -------------------------------------------------------------------------------- 1 | params: 2 | - name: ${1:name} 3 | value: ${2:value} 4 | resources: 5 | inputs: 6 | - name: ${3:source} 7 | resource: ${4:app-source} 8 | outputs: 9 | - name: ${5:builtImage} 10 | resource: ${6:app-image} 11 | -------------------------------------------------------------------------------- /rawsnippets/pipelinerun.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: 2 | kind: PipelineRun 3 | metadata: 4 | name: ${1:foo-run} 5 | spec: 6 | pipelineRef: 7 | name: ${2:foo} 8 | resources: 9 | - name: ${3:source} 10 | resourceRef: 11 | name: ${4:skaffold-source} 12 | -------------------------------------------------------------------------------- /rawsnippets/task.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: 2 | kind: Task 3 | metadata: 4 | name: ${1} 5 | spec: 6 | $LINE_COMMENT params: 7 | resources: 8 | inputs: 9 | resources: 10 | - name: ${2:workspace} 11 | type: ${3:git} 12 | targetPath: ${4:target-workspace} 13 | outputs: 14 | resources: 15 | - name: ${5} 16 | type: ${6} 17 | steps: 18 | - name: ${5:build-sources} 19 | image: ${6:ubuntu} 20 | command: 21 | - ${7:/bin/bash} 22 | args: ${8:['-c', 'echo hello world']} 23 | -------------------------------------------------------------------------------- /rawsnippets/taskinput.yaml: -------------------------------------------------------------------------------- 1 | params: 2 | - name: ${1:foo} 3 | description: ${2:Parameter description} 4 | default: ${3:default value} 5 | type: ${4:string} 6 | resources: 7 | inputs: 8 | resources: 9 | - name: ${5:source} 10 | type: ${6|git,image,pullRequest,cluster,storage|} 11 | outputs: 12 | resources: 13 | - name: ${7:builtImage} 14 | outputImageDir: ${8:path/to/image} 15 | targetPath: "" 16 | type: image 17 | $LINE_COMMENT steps: 18 | -------------------------------------------------------------------------------- /rawsnippets/taskrun.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: 2 | kind: TaskRun 3 | metadata: 4 | name: ${1:echo-hello-world-run} 5 | spec: 6 | taskRef: 7 | name: ${2:echo-hello-world} 8 | -------------------------------------------------------------------------------- /rawsnippets/tektonParameter.yaml: -------------------------------------------------------------------------------- 1 | - name: ${1:foo} 2 | value: ${2:bar} 3 | 4 | -------------------------------------------------------------------------------- /rawsnippets/tektonTaskParameter.yaml: -------------------------------------------------------------------------------- 1 | - name: ${1:foo} 2 | description: ${2:Parameter description} 3 | default: ${3:default value} 4 | type: ${4:string} -------------------------------------------------------------------------------- /rawsnippets/tektonTaskStep.yaml: -------------------------------------------------------------------------------- 1 | - name: ${2:echo2} 2 | image: ${3:fedora,quay.io/buildah/stable} 3 | workingDir: \"/workspace/source/${4:\\${inputs.params.contextDir}}\" 4 | command: 5 | - ${5:echo} 6 | args: 7 | - 'bye world' 8 | -------------------------------------------------------------------------------- /rawsnippets/triggerbinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: triggers.tekton.dev/v1beta1 2 | kind: TriggerBinding 3 | metadata: 4 | name: ${1:name} 5 | spec: 6 | params: 7 | - name: ${2:param_name} 8 | value: ${3:value} 9 | -------------------------------------------------------------------------------- /rawsnippets/triggertemplate.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: triggers.tekton.dev/v1beta1 2 | kind: TriggerTemplate 3 | metadata: 4 | name: ${1:name} 5 | spec: 6 | resourcetemplates: 7 | - ${0} 8 | -------------------------------------------------------------------------------- /src/check-cluster.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { Command } from './cli-command'; 7 | import { tkn } from './tkn'; 8 | 9 | export interface clusterVersion { 10 | items: [ 11 | { 12 | status: { 13 | desired: { 14 | version: string; 15 | }; 16 | }; 17 | }, 18 | ]; 19 | } 20 | 21 | export async function checkOpenShiftCluster(): Promise { 22 | try { 23 | const result = await tkn.execute(Command.checkOcpCluster(), process.cwd(), false); 24 | if (result?.stdout?.trim()) { 25 | // eslint-disable-next-line @typescript-eslint/no-unsafe-return 26 | return JSON.parse(result?.stdout); 27 | } 28 | // eslint-disable-next-line no-empty 29 | } catch (err) {} 30 | return null 31 | } 32 | -------------------------------------------------------------------------------- /src/cluster-version.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | 7 | import { cli } from './cli'; 8 | import { Command } from './cli-command'; 9 | 10 | interface Versions { 11 | openshift_Version: string; 12 | kubernetes_Version: string; 13 | } 14 | 15 | export async function getClusterVersions(): Promise { 16 | const ocpServerVersion = await getOcpServerVersion(); 17 | const kubectlVersion = await getK8sServerVersion(); 18 | return { 19 | kubernetes_Version: kubectlVersion, 20 | openshift_Version: ocpServerVersion 21 | }; 22 | } 23 | 24 | async function getK8sServerVersion(): Promise { 25 | const kubectlVersion = await cli.execute(Command.kubectlVersion()); 26 | if (kubectlVersion.stdout) { 27 | try { 28 | const versionsJson = JSON.parse(kubectlVersion.stdout); 29 | if (versionsJson?.serverVersion?.major && versionsJson?.serverVersion?.minor) { 30 | return `${versionsJson.serverVersion.major}.${versionsJson.serverVersion.minor}`; 31 | } 32 | } catch (err) { 33 | // ignore and return undefined 34 | } 35 | } 36 | return undefined; 37 | } 38 | 39 | async function getOcpServerVersion(): Promise { 40 | const result = await cli.execute(Command.getOcpServerVersion()); 41 | if (!result.error) { 42 | try { 43 | const versionsJson = JSON.parse(result.stdout); 44 | if (versionsJson?.status?.versions?.[0]?.version) { 45 | return versionsJson.status.versions[0].version; 46 | } 47 | } catch (err) { 48 | // ignore and return undefined 49 | } 50 | } 51 | return undefined; 52 | } 53 | -------------------------------------------------------------------------------- /src/commands.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { commands } from 'vscode'; 7 | import { customTektonExplorer } from './pipeline/customTektonExplorer'; 8 | import { telemetryLog } from './telemetry'; 9 | 10 | export enum VSCodeCommands { 11 | SetContext = 'setContext', 12 | } 13 | 14 | 15 | export enum CommandContext { 16 | TreeZenMode = 'tekton:zenMode', 17 | PipelinePreview = 'tekton:pipelinePreview', 18 | TknCli = 'tekton:tkn', 19 | Trigger = 'tekton:trigger', 20 | } 21 | 22 | 23 | export function setCommandContext(key: CommandContext | string, value: string | boolean): PromiseLike { 24 | return commands.executeCommand(VSCodeCommands.SetContext, key, value); 25 | } 26 | 27 | export function enterZenMode(): void { 28 | setCommandContext(CommandContext.TreeZenMode, true); 29 | customTektonExplorer.showSelected(true); 30 | 31 | } 32 | 33 | export function exitZenMode(): void { 34 | setCommandContext(CommandContext.TreeZenMode, false); 35 | customTektonExplorer.showSelected(false); 36 | } 37 | 38 | export function refreshCustomTree(commandId?: string): void { 39 | telemetryLog(commandId, 'Custom refresh command call'); 40 | customTektonExplorer.refresh(); 41 | } 42 | 43 | export function removeItemFromCustomTree(commandId?: string): void { 44 | telemetryLog(commandId, 'Custom remove command call'); 45 | customTektonExplorer.removeItem(); 46 | } 47 | -------------------------------------------------------------------------------- /src/commands/common.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { Disposable, commands } from 'vscode'; 7 | 8 | interface CommandConstructor { 9 | new(): Command; 10 | } 11 | 12 | const registrableCommands: CommandConstructor[] = []; 13 | 14 | export function command(): ClassDecorator { 15 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 16 | return (target: any) => { 17 | registrableCommands.push(target); 18 | }; 19 | } 20 | 21 | export abstract class Command implements Disposable { 22 | 23 | private readonly disposable: Disposable; 24 | constructor(id: string) { 25 | if (id) { 26 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 27 | this.disposable = commands.registerCommand(id, (...args: any[]) => this.execute(...args)) 28 | } 29 | } 30 | 31 | dispose(): void { 32 | this.disposable?.dispose() 33 | } 34 | 35 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 36 | abstract execute(...args: any[]): any; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | export const IS_CLUSTER_INACTIVE = 'tekton.cluster.inactive'; 6 | export const IS_TEKTON_PIPELINES_INACTIVE = 'tekton.pipelines.inactive'; 7 | 8 | export const ERR_CLUSTER_TIMED_OUT = 'the cluster took too long to respond'; 9 | 10 | export const DEFAULT_EXEC_TIMEOUT = 10000; 11 | export const CHECK_USER_AUTHENTICATION_TIMEOUT = 5000; 12 | -------------------------------------------------------------------------------- /src/context-type.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | export enum ContextType { 7 | TASK = 'task', 8 | TASKRUN = 'taskrun', 9 | PIPELINE = 'pipeline', 10 | PIPELINERUN = 'pipelinerun', 11 | PIPELINERUNCHILDNODE = 'pipelineRunFinished', 12 | CLUSTERTASK = 'clustertask', 13 | TASKRUNNODE = 'taskrunnode', 14 | PIPELINENODE = 'pipelinenode', 15 | PIPELINERESOURCENODE = 'pipelineresourcenode', 16 | PIPELINERESOURCE = 'pipelineresource', 17 | TASKNODE = 'tasknode', 18 | CLUSTERTASKNODE = 'clustertasknode', 19 | TKN_DOWN = 'tknDown', 20 | TRIGGERTEMPLATESNODE = 'triggertemplatesnode', 21 | TRIGGERTEMPLATES = 'triggertemplates', 22 | TRIGGERBINDINGNODE = 'triggerbindingnode', 23 | TRIGGERBINDING = 'triggerbinding', 24 | CLUSTERTRIGGERBINDINGNODE = 'clustertriggerbindingnode', 25 | CLUSTERTRIGGERBINDING = 'clustertriggerbinding', 26 | EVENTLISTENERNODE = 'eventlistenernode', 27 | EVENTLISTENER = 'eventlistener', 28 | CONDITIONSNODE = 'conditionsnode', 29 | CONDITIONS = 'conditions', 30 | PIPELINERUNNODE = 'pipelinerunnode', 31 | CONDITIONTASKRUN = 'tr', 32 | DEBUGGER = 'debugger' 33 | } 34 | -------------------------------------------------------------------------------- /src/debugger/cancel-taskrun.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { window } from 'vscode'; 7 | import { Command } from '../cli-command'; 8 | import { telemetryLogError } from '../telemetry'; 9 | import { tkn } from '../tkn'; 10 | import { TektonNode } from '../tree-view/tekton-node'; 11 | import { debugSessions } from '../util/map-object'; 12 | import { getStderrString } from '../util/stderrstring'; 13 | 14 | export async function cancelTaskRun(taskRun: TektonNode, commandId?: string): Promise { 15 | if (!taskRun) return null; 16 | const continueTaskRun = debugSessions.get(taskRun.getName()); 17 | const result = await tkn.execute(Command.cancelTaskRun(continueTaskRun.resourceName), process.cwd(), false); 18 | if (result.error) { 19 | telemetryLogError(commandId, `Fail to debug fail continue ${getStderrString(result.error)}.`); 20 | window.showErrorMessage(`Fail to debug fail continue ${getStderrString(result.error)}.`); 21 | return null; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/debugger/debug-continue.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { window } from 'vscode'; 7 | import { Command } from '../cli-command'; 8 | import { telemetryLogError } from '../telemetry'; 9 | import { tkn } from '../tkn'; 10 | import { TektonNode } from '../tree-view/tekton-node'; 11 | import { debugSessions } from '../util/map-object'; 12 | import { getStderrString } from '../util/stderrstring'; 13 | 14 | 15 | export async function showDebugContinue(taskRun: TektonNode, commandId?: string): Promise { 16 | if (!taskRun) return null; 17 | const continueTaskRun = debugSessions.get(taskRun.getName()); 18 | const result = await tkn.execute(Command.debugContinue(continueTaskRun.containerName, continueTaskRun.podName, continueTaskRun.namespace), process.cwd(), false); 19 | if (result.error && !result.stdout) { 20 | telemetryLogError(commandId, `Fail to continue debug ${getStderrString(result.error)}.`); 21 | window.showErrorMessage(`Fail to continue debug ${getStderrString(result.error)}.`); 22 | return null; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/debugger/debug-fail-continue.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { window } from 'vscode'; 7 | import { Command } from '../cli-command'; 8 | import { telemetryLogError } from '../telemetry'; 9 | import { tkn } from '../tkn'; 10 | import { TektonNode } from '../tree-view/tekton-node'; 11 | import { debugSessions } from '../util/map-object'; 12 | import { getStderrString } from '../util/stderrstring'; 13 | 14 | export async function showDebugFailContinue(taskRun: TektonNode, commandId?: string): Promise { 15 | if (!taskRun) return null; 16 | const continueTaskRun = debugSessions.get(taskRun.getName()); 17 | const result = await tkn.execute(Command.debugFailContinue(continueTaskRun.containerName, continueTaskRun.podName, continueTaskRun.namespace), process.cwd(), false); 18 | if (result.error && !result.stdout) { 19 | telemetryLogError(commandId, `Fail to debug fail continue ${getStderrString(result.error)}.`); 20 | window.showErrorMessage(`Fail to debug fail continue ${getStderrString(result.error)}.`); 21 | return null; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/debugger/delete-debugger.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { window } from 'vscode'; 7 | import { debugSessions } from '../util/map-object'; 8 | import { debugExplorer } from './debugExplorer'; 9 | 10 | 11 | export function deleteDebugger(name: string): void { 12 | debugSessions.delete(name); 13 | const activeTerminal = window.terminals; 14 | activeTerminal.map((terminal) => { 15 | if (terminal.name.trim() === `Tekton:${name}`) { 16 | terminal.dispose(); 17 | } 18 | }); 19 | debugExplorer.refresh(); 20 | } 21 | -------------------------------------------------------------------------------- /src/debugger/show-in-terminal.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { window } from 'vscode'; 7 | import { Command } from '../cli-command'; 8 | import { telemetryLog } from '../telemetry'; 9 | import { tkn } from '../tkn'; 10 | import { TektonNode } from '../tree-view/tekton-node'; 11 | import { debugSessions } from '../util/map-object'; 12 | 13 | export async function openContainerInTerminal(taskRun: TektonNode, commandId?: string): Promise { 14 | if (!taskRun) return null; 15 | const activeTerminal = window.terminals; 16 | activeTerminal.map((terminal) => { 17 | if (terminal.name.trim() === `Tekton:${taskRun.getName()}`) { 18 | terminal.dispose(); 19 | } 20 | }); 21 | const debugTaskRun = debugSessions.get(taskRun.getName()); 22 | telemetryLog(commandId, 'Open container in terminal command click') 23 | tkn.executeInTerminal(Command.loginToContainer(debugTaskRun.containerName, debugTaskRun.podName, debugTaskRun.namespace), debugTaskRun.resourceName); 24 | } 25 | -------------------------------------------------------------------------------- /src/hub/hub-common.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { ResourceData, ResourceVersionData } from '../tekton-hub-client/api'; 7 | 8 | export interface HubResourceInstallation { 9 | url: string; 10 | name: string; 11 | kind: string; 12 | tknVersion?: string; 13 | minPipelinesVersion?: string; 14 | asClusterTask: boolean; 15 | resourceVersion?: ResourceVersionData; 16 | view: string; 17 | } 18 | 19 | export interface HubResourceUninstall { 20 | name: string; 21 | kind: string; 22 | clusterTask: boolean; 23 | } 24 | 25 | export interface InstalledResource extends ResourceData { 26 | installedVersion?: ResourceVersionData; 27 | clusterTask?: boolean; 28 | } 29 | 30 | export type HubResource = (InstalledResource | ResourceData) & { view?: string } 31 | 32 | export function isInstalledTask(task: HubResource): task is InstalledResource { 33 | return (task as InstalledResource).installedVersion !== undefined; 34 | } 35 | -------------------------------------------------------------------------------- /src/hub/hub-recommendation.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import * as vscode from 'vscode'; 7 | import { getProjectType } from '../project-analizer/language-recongnizer/recognazer' 8 | 9 | const MAX_LANG_AND_TOOLS = 10; 10 | export async function startDetectingLanguage(): Promise { 11 | const folder = vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders[0]; 12 | if (folder) { 13 | try { 14 | const langAndTools = await getProjectType(folder.uri.fsPath); 15 | if (langAndTools && langAndTools.length > 0) { 16 | 17 | const result = []; 18 | for (const element of langAndTools) { 19 | result.push(element.name); 20 | result.push(element.builder); 21 | if (element.frameworks){ 22 | result.push(...element.frameworks); 23 | } 24 | if (result.length >= MAX_LANG_AND_TOOLS) { 25 | break; 26 | } 27 | } 28 | 29 | return result; 30 | } 31 | } catch (err) { 32 | console.error(err); 33 | } 34 | } 35 | 36 | return []; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/hub/task-page-manager.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | import { ViewColumn } from 'vscode'; 6 | import { Disposable } from '../util/disposable'; 7 | import { HubResource } from './hub-common'; 8 | import { TaskPageView } from './task-page-view'; 9 | 10 | 11 | 12 | 13 | export class TaskPageManager extends Disposable { 14 | 15 | private activePreview: TaskPageView | undefined = undefined; 16 | 17 | constructor() { 18 | super(); 19 | } 20 | 21 | showTaskPageView(task: HubResource, tknVersion: string): void { 22 | if (!this.activePreview){ 23 | this.createTaskPageView(task, tknVersion); 24 | 25 | } else { 26 | this.activePreview.update(task); 27 | } 28 | } 29 | 30 | createTaskPageView(task: HubResource, tknVersion: string): TaskPageView { 31 | const preview = TaskPageView.create(task, tknVersion, ViewColumn.One); 32 | 33 | this.activePreview = preview; 34 | return this.registerPipelinePreview(preview); 35 | } 36 | 37 | private registerPipelinePreview(preview: TaskPageView): TaskPageView { 38 | 39 | this.trackActive(preview); 40 | return preview; 41 | } 42 | 43 | private trackActive(preview: TaskPageView): void { 44 | preview.onDidChangeViewState(({ webviewPanel }) => { 45 | this.activePreview = webviewPanel.active ? preview : undefined; 46 | }); 47 | 48 | preview.onDispose(() => { 49 | if (this.activePreview === preview) { 50 | this.activePreview = undefined; 51 | } 52 | }); 53 | } 54 | 55 | } 56 | 57 | export const taskPageManager = new TaskPageManager(); 58 | -------------------------------------------------------------------------------- /src/hub/uninstall-task.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { tkn } from '../tkn'; 7 | import { HubResourceUninstall } from './hub-common'; 8 | import * as vscode from 'vscode'; 9 | import { getStderrString } from '../util/stderrstring'; 10 | import { Command } from '../cli-command'; 11 | import { CliCommand } from '../cli'; 12 | import { telemetryLog, telemetryLogError } from '../telemetry'; 13 | 14 | const uninstallTaskEmitter = new vscode.EventEmitter(); 15 | export const uninstallTaskEvent = uninstallTaskEmitter.event; 16 | 17 | export async function uninstallTask(task: HubResourceUninstall): Promise { 18 | let command: CliCommand; 19 | let message: string; 20 | if (task.kind === 'Task'){ 21 | if (task.clusterTask){ 22 | command = Command.deleteClusterTask(task.name); 23 | } else { 24 | command = Command.deleteTask(task.name); 25 | } 26 | } else { 27 | command = Command.deletePipeline(task.name); 28 | } 29 | 30 | const result = await tkn.execute(command); 31 | if (result.error){ 32 | message = `Failed to uninstall: : ${getStderrString(result.error)}`; 33 | telemetryLogError('tekton.hub.uninstall', message); 34 | vscode.window.showWarningMessage(message); 35 | } else { 36 | message = `Resource ${task.name} uninstalled.`; 37 | telemetryLog('tekton.hub.uninstall', message); 38 | vscode.window.showInformationMessage(message); 39 | uninstallTaskEmitter.fire(task); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/humanizer.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | import * as humanize from 'humanize-duration'; 6 | 7 | export const humanizer = humanize.humanizer(createConfig()); 8 | function createConfig(): humanize.HumanizerOptions { 9 | return { 10 | language: 'shortEn', 11 | languages: { 12 | shortEn: { 13 | y: () => 'y', 14 | mo: () => 'mo', 15 | w: () => 'w', 16 | d: () => 'd', 17 | h: () => 'h', 18 | m: () => 'm', 19 | s: () => 's', 20 | ms: () => 'ms', 21 | } 22 | }, 23 | round: true, 24 | largest: 2, 25 | conjunction: ' ' 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /src/icon-path.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | export const IMAGES = '../../../images'; 7 | export const ERROR_PATH = '../../../images/generated/error'; 8 | export const PENDING_PATH = '../../../images/generated/pending'; 9 | -------------------------------------------------------------------------------- /src/model/element-type.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | export enum TknElementType { 7 | DOCUMENT, 8 | PIPELINE, 9 | METADATA, 10 | PARAM, 11 | PARAMS, 12 | PIPELINE_SPEC, 13 | PIPELINE_RESOURCES, 14 | PIPELINE_RESOURCE, 15 | PIPELINE_TASKS, 16 | PIPELINE_TASK, 17 | PIPELINE_TASK_REF, 18 | VALUE, 19 | PARAM_SPECS, 20 | PARAM_SPEC, 21 | STRING_ARRAY, 22 | PIPELINE_WORKSPACES, 23 | PIPELINE_WORKSPACE, 24 | PIPELINE_TASK_CONDITIONS, 25 | PIPELINE_TASK_CONDITION, 26 | PIPELINE_TASK_INPUT_RESOURCES, 27 | PIPELINE_TASK_INPUT_RESOURCE, 28 | PIPELINE_TASK_INPUT_RESOURCE_FROM, 29 | PIPELINE_TASK_RUN_AFTER, 30 | PIPELINE_TASK_RESOURCES, 31 | PIPELINE_TASK_OUTPUTS_RESOURCE, 32 | PIPELINE_TASK_OUTPUTS_RESOURCES, 33 | PIPELINE_TASK_PARAMS, 34 | PIPELINE_TASK_WORKSPACE, 35 | PIPELINE_TASK_WORKSPACES, 36 | PIPELINE_TASK_WHEN, 37 | PIPELINE_TASK_WHEN_VALUES, 38 | EMBEDDED_TASK, 39 | PIPELINE_TASK_METADATA, 40 | TASK_RESULT, 41 | TASK_RESULTS, 42 | KEY 43 | } 44 | -------------------------------------------------------------------------------- /src/project-analizer/language-recongnizer/recognazer.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { ProjectType } from '../project-types'; 7 | import {detectLanguages} from '@redhat-developer/alizer'; 8 | 9 | export async function getProjectType(path: string): Promise { 10 | const result = await detectLanguages(path); 11 | return result; 12 | } 13 | -------------------------------------------------------------------------------- /src/project-analizer/project-types.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | export interface ProjectType { 7 | name: string; 8 | frameworks?: string[]; 9 | builder?: string; 10 | } 11 | -------------------------------------------------------------------------------- /src/tekton-hub-client/.openapi-generator-ignore: -------------------------------------------------------------------------------- 1 | # OpenAPI Generator Ignore 2 | # Generated by openapi-generator https://github.com/openapitools/openapi-generator 3 | 4 | # Use this file to prevent files from being overwritten by the generator. 5 | # The patterns follow closely to .gitignore or .dockerignore. 6 | 7 | # As an example, the C# client generator defines ApiClient.cs. 8 | # You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: 9 | #ApiClient.cs 10 | 11 | # You can match any string of characters against a directory, file or extension with a single asterisk (*): 12 | #foo/*/qux 13 | # The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux 14 | 15 | # You can recursively match patterns against a directory, file or extension with a double asterisk (**): 16 | #foo/**/qux 17 | # This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux 18 | 19 | # You can also negate patterns with an exclamation (!). 20 | # For example, you can ignore all files in a docs folder with the file extension .md: 21 | #docs/*.md 22 | # Then explicitly reverse the ignore rule for a single file: 23 | #!docs/README.md 24 | -------------------------------------------------------------------------------- /src/tekton-hub-client/base.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable 2 | /** 3 | * Tekton Hub 4 | * HTTP services for managing Tekton Hub 5 | * 6 | * The version of the OpenAPI document: 1.0 7 | * 8 | * 9 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 10 | * https://openapi-generator.tech 11 | * Do not edit the class manually. 12 | */ 13 | 14 | 15 | import { Configuration } from "./configuration"; 16 | // Some imports not used depending on template conditions 17 | // @ts-ignore 18 | import globalAxios, { AxiosPromise, AxiosInstance } from 'axios'; 19 | 20 | export const BASE_PATH = "https://api.hub.tekton.dev".replace(/\/+$/, ""); 21 | 22 | /** 23 | * 24 | * @export 25 | */ 26 | export const COLLECTION_FORMATS = { 27 | csv: ",", 28 | ssv: " ", 29 | tsv: "\t", 30 | pipes: "|", 31 | }; 32 | 33 | /** 34 | * 35 | * @export 36 | * @interface RequestArgs 37 | */ 38 | export interface RequestArgs { 39 | url: string; 40 | options: any; 41 | } 42 | 43 | /** 44 | * 45 | * @export 46 | * @class BaseAPI 47 | */ 48 | export class BaseAPI { 49 | protected configuration: Configuration | undefined; 50 | 51 | constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) { 52 | if (configuration) { 53 | this.configuration = configuration; 54 | this.basePath = configuration.basePath || this.basePath; 55 | } 56 | } 57 | }; 58 | 59 | /** 60 | * 61 | * @export 62 | * @class RequiredError 63 | * @extends {Error} 64 | */ 65 | export class RequiredError extends Error { 66 | name: "RequiredError" = "RequiredError"; 67 | constructor(public field: string, msg?: string) { 68 | super(msg); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/tekton-hub-client/configuration.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable 2 | /** 3 | * Tekton Hub 4 | * HTTP services for managing Tekton Hub 5 | * 6 | * The version of the OpenAPI document: 1.0 7 | * 8 | * 9 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 10 | * https://openapi-generator.tech 11 | * Do not edit the class manually. 12 | */ 13 | 14 | 15 | export interface ConfigurationParameters { 16 | apiKey?: string | Promise | ((name: string) => string) | ((name: string) => Promise); 17 | username?: string; 18 | password?: string; 19 | accessToken?: string | ((name?: string, scopes?: string[]) => string); 20 | basePath?: string; 21 | baseOptions?: any; 22 | } 23 | 24 | export class Configuration { 25 | /** 26 | * parameter for apiKey security 27 | * @param name security name 28 | * @memberof Configuration 29 | */ 30 | apiKey?: string | Promise | ((name: string) => string) | ((name: string) => Promise); 31 | /** 32 | * parameter for basic security 33 | * 34 | * @type {string} 35 | * @memberof Configuration 36 | */ 37 | username?: string; 38 | /** 39 | * parameter for basic security 40 | * 41 | * @type {string} 42 | * @memberof Configuration 43 | */ 44 | password?: string; 45 | /** 46 | * parameter for oauth2 security 47 | * @param name security name 48 | * @param scopes oauth2 scope 49 | * @memberof Configuration 50 | */ 51 | accessToken?: string | ((name?: string, scopes?: string[]) => string); 52 | /** 53 | * override base path 54 | * 55 | * @type {string} 56 | * @memberof Configuration 57 | */ 58 | basePath?: string; 59 | /** 60 | * base options for axios calls 61 | * 62 | * @type {any} 63 | * @memberof Configuration 64 | */ 65 | baseOptions?: any; 66 | 67 | constructor(param: ConfigurationParameters = {}) { 68 | this.apiKey = param.apiKey; 69 | this.username = param.username; 70 | this.password = param.password; 71 | this.accessToken = param.accessToken; 72 | this.basePath = param.basePath; 73 | this.baseOptions = param.baseOptions; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/tekton-hub-client/index.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable 2 | /** 3 | * Tekton Hub 4 | * HTTP services for managing Tekton Hub 5 | * 6 | * The version of the OpenAPI document: 1.0 7 | * 8 | * 9 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 10 | * https://openapi-generator.tech 11 | * Do not edit the class manually. 12 | */ 13 | 14 | 15 | export * from "./api"; 16 | export * from "./configuration"; 17 | -------------------------------------------------------------------------------- /src/tekton/clustertask.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { TektonItem } from './tektonitem'; 7 | import { CliCommand } from '../cli'; 8 | import { TektonNode } from '../tree-view/tekton-node'; 9 | import { Command } from '../cli-command'; 10 | import { createWizardForTaskOrClusterTask } from './create-wizard-for-task-or-clustertask'; 11 | import { ClusterTaskModel } from '../util/resource-kind'; 12 | 13 | export class ClusterTask extends TektonItem { 14 | 15 | static async start(clusterTask: TektonNode, commandId?: string): Promise { 16 | if (!clusterTask) return null; 17 | await createWizardForTaskOrClusterTask(clusterTask.getName(), ClusterTaskModel.kind, commandId); 18 | } 19 | 20 | static getDeleteCommand(item: TektonNode): CliCommand { 21 | return Command.deleteClusterTask(item.getName()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/tekton/clustertriggerbunding.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { TektonItem } from './tektonitem'; 7 | import { CliCommand } from '../cli'; 8 | import { TektonNode } from '../tree-view/tekton-node'; 9 | import { Command } from '../cli-command'; 10 | 11 | export class ClusterTriggerBinding extends TektonItem { 12 | static getDeleteCommand(item: TektonNode): CliCommand { 13 | return Command.deleteClusterTriggerBinding(item.getName()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/tekton/condition.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | 7 | import { TektonItem } from './tektonitem'; 8 | import { CliCommand } from '../cli'; 9 | import { TektonNode } from '../tree-view/tekton-node'; 10 | import { Command } from '../cli-command'; 11 | 12 | export class Condition extends TektonItem { 13 | 14 | static getDeleteCommand(condition: TektonNode): CliCommand { 15 | return Command.deleteCondition(condition.getName()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/tekton/create-resources.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { k8sCreate } from './addtrigger'; 7 | 8 | 9 | export interface NewPvc { 10 | apiVersion: string; 11 | kind: string; 12 | metadata: { 13 | name: string; 14 | generateName?: string; 15 | }; 16 | spec: { 17 | accessMode: string[]; 18 | resources: { 19 | requests: { 20 | storage: string; 21 | }; 22 | }; 23 | volumeMode: string; 24 | }; 25 | } 26 | 27 | export interface NewPipelineResources { 28 | apiVersion: string; 29 | kind: string; 30 | metadata: { 31 | name?: string; 32 | generateName?: string; 33 | }; 34 | spec: { 35 | params: [ 36 | { 37 | name: string; 38 | value: string; 39 | } 40 | ]; 41 | type: string; 42 | }; 43 | } 44 | 45 | export async function createNewResource(resources: NewPvc[] | NewPipelineResources[]): Promise { 46 | if (resources.length === 0) return null; 47 | for (const resource of resources) { 48 | await k8sCreate(resource); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/tekton/eventlistener.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { TektonItem } from './tektonitem'; 7 | import { CliCommand } from '../cli'; 8 | import { TektonNode } from '../tree-view/tekton-node'; 9 | import { Command } from '../cli-command'; 10 | 11 | export class EventListener extends TektonItem { 12 | 13 | static getDeleteCommand(item: TektonNode): CliCommand { 14 | return Command.deleteEventListeners(item.getName()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/tekton/pipelineresource.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { TektonItem } from './tektonitem'; 7 | import { window } from 'vscode'; 8 | import { CliCommand } from '../cli'; 9 | import { TektonNode } from '../tree-view/tekton-node'; 10 | import { Command } from '../cli-command'; 11 | 12 | export class PipelineResource extends TektonItem { 13 | 14 | static async describe(pipelineResource: TektonNode): Promise { 15 | if (!pipelineResource) { 16 | pipelineResource = await window.showQuickPick(await PipelineResource.getPipelineResourceNames(), { placeHolder: 'Select Pipeline Resource to describe', ignoreFocusOut: true }); 17 | } 18 | if (!pipelineResource) return null; 19 | PipelineResource.tkn.executeInTerminal(Command.describePipelineResource(pipelineResource.getName())); 20 | } 21 | 22 | static getDeleteCommand(item: TektonNode): CliCommand { 23 | return Command.deletePipelineResource(item.getName()) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/tekton/task-run-data.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { window } from 'vscode'; 7 | import { Command } from '../cli-command'; 8 | import { TknTaskRun } from '../tekton'; 9 | import { tkn } from '../tkn'; 10 | 11 | 12 | export async function getTaskRunData(taskRunName: string): Promise{ 13 | const result = await tkn.execute(Command.getTaskRun(taskRunName), undefined, false); 14 | if (result.error) { 15 | window.showErrorMessage(`TaskRun not Found: ${result.error}`) 16 | return null; 17 | } 18 | let data: TknTaskRun; 19 | try { 20 | data = JSON.parse(result.stdout); 21 | // eslint-disable-next-line no-empty 22 | } catch (ignore) { 23 | } 24 | return data; 25 | } 26 | -------------------------------------------------------------------------------- /src/tekton/task.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { TektonItem } from './tektonitem'; 7 | import { window } from 'vscode'; 8 | import * as cliInstance from '../cli'; 9 | import { createWizardForTaskOrClusterTask } from './create-wizard-for-task-or-clustertask'; 10 | import { TektonNode } from '../tree-view/tekton-node'; 11 | import { Command } from '../cli-command'; 12 | import { TaskModel } from '../util/resource-kind'; 13 | 14 | 15 | export class Task extends TektonItem { 16 | 17 | static async start(task: TektonNode, commandId?: string): Promise { 18 | if (!task) { 19 | task = await window.showQuickPick(await Task.getTaskNames(), { placeHolder: 'Select Task to start', ignoreFocusOut: true }); 20 | } 21 | if (!task) return null; 22 | return await createWizardForTaskOrClusterTask(task.getName(), TaskModel.kind ,commandId); 23 | } 24 | 25 | static getDeleteCommand(item: TektonNode): cliInstance.CliCommand { 26 | return Command.deleteTask(item.getName()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/tekton/triggerbinding.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | 7 | import { TektonItem } from './tektonitem'; 8 | import { CliCommand } from '../cli'; 9 | import { TektonNode } from '../tree-view/tekton-node'; 10 | import { Command } from '../cli-command'; 11 | 12 | 13 | export class TriggerBinding extends TektonItem { 14 | 15 | static getDeleteCommand(item: TektonNode): CliCommand { 16 | return Command.deleteTriggerBinding(item.getName()) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/tree-view/conditon-node.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { TreeItemCollapsibleState } from 'vscode'; 7 | import { ContextType } from '../context-type'; 8 | import { BaseTaskRun } from './task-run-node'; 9 | import { PipelineRunConditionCheckStatus } from '../tekton'; 10 | import { TektonNode } from './tekton-node'; 11 | import { Tkn } from '../tkn'; 12 | 13 | 14 | 15 | export class ConditionRun extends BaseTaskRun { 16 | constructor(parent: TektonNode, name: string, shortName: string, tkn: Tkn, item: PipelineRunConditionCheckStatus, uid: string) { 17 | super(parent, name, shortName, ContextType.CONDITIONTASKRUN, tkn, TreeItemCollapsibleState.None, uid, item.status?.startTime, item.status?.completionTime, item.status) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/tree-view/expand-node.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { ProviderResult, TreeItem, TreeItemCollapsibleState } from 'vscode'; 7 | import { TektonNode } from './tekton-node'; 8 | 9 | export class MoreNode extends TreeItem implements TektonNode { 10 | contextValue: string; 11 | creationTime?: string; 12 | state?: string; 13 | detail?: string; 14 | picked?: boolean; 15 | alwaysShow?: boolean; 16 | label: string; 17 | tooltip: string; 18 | description: string; 19 | 20 | constructor(private showNext: number, 21 | private totalCount: number, 22 | private parent: TektonNode) { 23 | super('more', TreeItemCollapsibleState.None); 24 | this.command = { command: '_tekton.explorer.more', title: `more ${this.showNext}`, arguments: [this.showNext, this.parent] }; 25 | this.tooltip = `${this.showNext} more from ${this.totalCount}`; 26 | this.description = `${this.showNext} from ${this.totalCount}`; 27 | 28 | } 29 | 30 | getChildren(): ProviderResult { 31 | throw new Error('Method not implemented.'); 32 | } 33 | getParent(): TektonNode { 34 | return this.parent; 35 | } 36 | getName(): string { 37 | return this.label; 38 | } 39 | 40 | refresh(): Promise { 41 | return Promise.resolve(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/tree-view/taskrun-for-pipeline-node.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { ProviderResult, TreeItemCollapsibleState } from 'vscode'; 7 | import { ContextType } from '../context-type'; 8 | import { TaskRun } from '../tekton'; 9 | import { TektonNode } from './tekton-node'; 10 | import { compareTimeNewestFirst, Tkn } from '../tkn'; 11 | import { BaseTaskRun } from './task-run-node'; 12 | import { ConditionRun } from './conditon-node'; 13 | 14 | export class TaskRunFromPipeline extends BaseTaskRun { 15 | constructor(parent: TektonNode, name: string, shortName: string, tkn: Tkn, private rawTaskRun: TaskRun, uid: string) { 16 | super(parent, 17 | name, 18 | shortName, 19 | ContextType.TASKRUN, 20 | tkn, 21 | rawTaskRun.conditionChecks ? TreeItemCollapsibleState.Collapsed : TreeItemCollapsibleState.None, 22 | uid, 23 | rawTaskRun.status?.startTime, 24 | rawTaskRun.status?.completionTime, 25 | rawTaskRun.status); 26 | } 27 | 28 | getChildren(): ProviderResult { 29 | if (this.rawTaskRun.conditionChecks) { 30 | const result = [] 31 | for (const conditionName in this.rawTaskRun.conditionChecks) { 32 | const rawCondition = this.rawTaskRun.conditionChecks[conditionName]; 33 | result.push(new ConditionRun(this, conditionName, rawCondition.conditionName, this.tkn, rawCondition, this.uid)); 34 | } 35 | return result.sort(compareTimeNewestFirst); 36 | } else { 37 | return super.getChildren(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/util/archive.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import * as fs from 'fs'; 7 | import * as zlib from 'zlib'; 8 | import targz = require('targz'); 9 | import unzipm = require('unzip-stream'); 10 | 11 | export class Archive { 12 | static unzip(zipFile: string, extractTo: string, prefix?: string): Promise { 13 | return new Promise((resolve, reject) => { 14 | if (zipFile.endsWith('.tar.gz')) { 15 | targz.decompress({ 16 | src: zipFile, 17 | dest: extractTo, 18 | tar: { 19 | map: (header) => { 20 | prefix && header.name.startsWith(prefix) ? header.name = header.name.substring(prefix.length) : header; 21 | return header; 22 | } 23 | } 24 | }, (err) => { 25 | err ? reject(err) : resolve(); 26 | }); 27 | } 28 | else if (zipFile.endsWith('.gz')) { 29 | Archive.gunzip(zipFile, extractTo) 30 | .then(resolve) 31 | .catch(reject); 32 | } 33 | else if (zipFile.endsWith('.zip')) { 34 | fs.createReadStream(zipFile) 35 | .pipe(unzipm.Extract({ path: extractTo })) 36 | .on('error', reject) 37 | .on('close', resolve); 38 | } 39 | else { 40 | reject(`Unsupported extension for '${zipFile}'`); 41 | } 42 | }); 43 | } 44 | 45 | static gunzip(source, destination): Promise { 46 | return new Promise((res, rej) => { 47 | const src = fs.createReadStream(source); 48 | const dest = fs.createWriteStream(destination); 49 | src.pipe(zlib.createGunzip()).pipe(dest); 50 | dest.on('close', res); 51 | dest.on('error', rej); 52 | src.on('error', rej); 53 | }); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/util/check-ref-resource.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { TknPipeline } from '../tekton'; 7 | import { TektonNode } from '../tree-view/tekton-node'; 8 | import * as vscode from 'vscode'; 9 | 10 | const tektonResource = { 11 | task: 'Task', 12 | clustertask: 'ClusterTask' 13 | } 14 | 15 | export function referenceOfTaskAndClusterTaskInCluster(item: TektonNode, pipelineList: TknPipeline[]): boolean { 16 | const found = pipelineList.some((value) => { 17 | if (value?.spec?.tasks) { 18 | return value?.spec?.tasks.some((task) => { 19 | if (task?.taskRef?.kind === tektonResource[item.contextValue] && task?.taskRef?.name === item.getName()) { 20 | return true; 21 | } 22 | }) 23 | } 24 | }); 25 | return found; 26 | } 27 | 28 | export function checkRefResource(): boolean { 29 | return vscode.workspace 30 | .getConfiguration('vs-tekton') 31 | .get('refResource'); 32 | } 33 | -------------------------------------------------------------------------------- /src/util/detection.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { CommandContext, setCommandContext } from '../commands'; 7 | import { TknVersion, version } from './tknversion'; 8 | 9 | export async function triggerDetection(): Promise { 10 | setCommandContext(CommandContext.Trigger, false); 11 | const tknVersionType: TknVersion = await version(); 12 | if (tknVersionType && tknVersionType.trigger !== 'unknown') { 13 | setCommandContext(CommandContext.Trigger, true); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/util/disposable.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | import * as vscode from 'vscode'; 6 | 7 | export class Disposable { 8 | protected disposed = false; 9 | 10 | protected disposables: vscode.Disposable[] = []; 11 | 12 | dispose(): void { 13 | if (this.disposed) { 14 | return; 15 | } 16 | this.disposed = true; 17 | disposeAll(this.disposables); 18 | } 19 | 20 | register(value: T): T { 21 | if (this.disposed) { 22 | value.dispose(); 23 | } else { 24 | this.disposables.push(value); 25 | } 26 | return value; 27 | } 28 | 29 | protected get isDisposed(): boolean { 30 | return this.disposed; 31 | } 32 | } 33 | 34 | export function disposeAll(disposables: vscode.Disposable[]): void { 35 | disposables.forEach(d => { 36 | if (d) { 37 | d.dispose(); 38 | } 39 | }); 40 | } 41 | -------------------------------------------------------------------------------- /src/util/download.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import * as fs from 'fs-extra'; 7 | import request = require('request'); 8 | import progress = require('request-progress'); 9 | 10 | export class DownloadUtil { 11 | static downloadFile(fromUrl: string, toFile: string, progressCallBack?: (current: number, increment: number) => void, throttle?: number): Promise { 12 | return new Promise((resolve, reject) => { 13 | let previous = 0; 14 | progress(request(fromUrl), { 15 | throttle: throttle || 250, 16 | delay: 0, 17 | lengthHeader: 'content-length' 18 | }).on('progress', (state: { percent: number }) => { 19 | const current = Math.round(state.percent * 100); 20 | current !== previous && progressCallBack && progressCallBack(current, current - previous); 21 | previous = current; 22 | }).on('error', reject) 23 | .on('end', () => progressCallBack && progressCallBack(100, 100 - previous)) 24 | .pipe(fs.createWriteStream(toFile)) 25 | .on('close', resolve) 26 | .on('error', reject); 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/util/exposeurl.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import * as _ from 'lodash'; 7 | import { Command } from '../cli-command'; 8 | import { tkn } from '../tkn'; 9 | 10 | 11 | export async function getExposeURl(name: string): Promise { 12 | const result = await tkn.execute(Command.getRoute(name)); 13 | const route = JSON.parse(result.stdout); 14 | const scheme = _.get(route, 'spec.tls.termination') ? 'https' : 'http'; 15 | let url = `${scheme}://${route.spec.host}`; 16 | if (route.spec?.path) { 17 | url += route.spec.path; 18 | } 19 | return url; 20 | } 21 | -------------------------------------------------------------------------------- /src/util/filename.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | const id = new RegExp('^[A-Za-z0-9]+'); 7 | const uidRegex = new RegExp('@[A-Za-z0-9]+$'); 8 | 9 | export function newFileName(name: string, uid: string): string { 10 | return `${name}@${uid.match(id)[0]}`; 11 | } 12 | 13 | export function originalFileName(name: string): string { 14 | return name.replace(uidRegex, ''); 15 | } 16 | -------------------------------------------------------------------------------- /src/util/list-tekton-resource.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { CliCommand } from '../cli'; 7 | import { Command } from '../cli-command'; 8 | import { TknPipeline } from '../tekton'; 9 | import { tkn } from '../tkn'; 10 | import { ToolsConfig } from '../tools'; 11 | 12 | export async function getPipelineList(): Promise { 13 | return await executeCommand(Command.listPipelines()); 14 | } 15 | 16 | export async function getResourceList(resource: string): Promise { 17 | return await executeCommand(Command.resourceList(resource)); 18 | } 19 | 20 | async function executeCommand(command: CliCommand): Promise { 21 | if (!ToolsConfig.getToolLocation('kubectl')) return []; 22 | const result = await tkn.execute(command); 23 | let data: TknPipeline[] = []; 24 | try { 25 | const r = JSON.parse(result.stdout); 26 | data = r.items ? r.items : data; 27 | } catch (ignore) { 28 | // ignore 29 | } 30 | return data; 31 | } 32 | -------------------------------------------------------------------------------- /src/util/log-in-editor.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { CliCommand } from '../cli'; 7 | import { tkn } from '../tkn'; 8 | import * as vscode from 'vscode'; 9 | 10 | 11 | class LogDocumentProvider implements vscode.TextDocumentContentProvider { 12 | onDidChangeEmitter = new vscode.EventEmitter(); 13 | onDidChange = this.onDidChangeEmitter.event; 14 | 15 | private documentMap = new Map(); 16 | 17 | provideTextDocumentContent(uri: vscode.Uri): vscode.ProviderResult { 18 | if (this.documentMap.has(uri.toString())){ 19 | return this.documentMap.get(uri.toString()); 20 | } 21 | return undefined; 22 | } 23 | 24 | addDocument(uri: vscode.Uri): void { 25 | this.documentMap.set(uri.toString(), ''); 26 | } 27 | 28 | updateDocument(uri: vscode.Uri, change: string): void { 29 | this.documentMap.set(uri.toString(), this.documentMap.get(uri.toString()) + change); 30 | this.onDidChangeEmitter.fire(uri); 31 | } 32 | 33 | deleteDocument(uri: vscode.Uri): void { 34 | this.documentMap.delete(uri.toString()); 35 | } 36 | } 37 | 38 | const logProvider = new LogDocumentProvider(); 39 | 40 | 41 | export function registerLogDocumentProvider(): vscode.Disposable { 42 | return vscode.workspace.registerTextDocumentContentProvider('tkn-log', logProvider); 43 | } 44 | 45 | export async function showLogInEditor(command: CliCommand, title: string): Promise { 46 | const process = tkn.executeWatch(command); 47 | const uri = vscode.Uri.parse(`tkn-log:${title}`) 48 | 49 | logProvider.addDocument(uri); 50 | vscode.window.showTextDocument(uri); 51 | 52 | process.stdout.setEncoding('utf8'); 53 | process.stderr.setEncoding('utf8'); 54 | process.stdout.on('data', (chunk) => { 55 | logProvider.updateDocument(uri, chunk); 56 | }); 57 | 58 | process.stderr.on('data', chunk => { 59 | logProvider.updateDocument(uri, chunk); 60 | }); 61 | 62 | process.on('close', () => { 63 | logProvider.updateDocument(uri, '\n>>>RUN FINISHED<<<'); 64 | logProvider.deleteDocument(uri); 65 | }); 66 | } 67 | 68 | -------------------------------------------------------------------------------- /src/util/map-object.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { DebugSessionEntry } from '../debugger/debug-tree-view'; 7 | 8 | 9 | export const debugName: Map = new Map(); 10 | export const debugSessions: Map = new Map(); 11 | export const pipelineTriggerStatus = new Map(); 12 | export const clusterPipelineStatus: Map = new Map(); 13 | -------------------------------------------------------------------------------- /src/util/platform.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | 'use strict'; 7 | 8 | export class Platform { 9 | 10 | static identify(map): string | undefined { 11 | if (map[Platform.OS]) { 12 | return map[Platform.OS](); 13 | } 14 | return map['default'] ? map['default']() : undefined; 15 | } 16 | 17 | static getOS(): string { 18 | return process.platform; 19 | } 20 | 21 | static get OS(): string { 22 | return Platform.getOS(); 23 | } 24 | 25 | static get ENV(): NodeJS.ProcessEnv { 26 | return Platform.getEnv(); 27 | } 28 | 29 | static getEnv(): NodeJS.ProcessEnv { 30 | return process.env; 31 | } 32 | 33 | static getUserHomePath(): string { 34 | return Platform.identify({ 35 | win32: () => Platform.ENV.USERPROFILE, 36 | default: () => Platform.ENV.HOME 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/util/resource-kind.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { K8sKind } from '../tekton/k8s-type'; 7 | 8 | export const TriggerTemplateModel = { 9 | apiGroup: 'triggers.tekton.dev', 10 | apiVersion: 'v1alpha1', 11 | kind: 'TriggerTemplate', 12 | }; 13 | 14 | export const EventListenerModel: K8sKind = { 15 | apiGroup: 'triggers.tekton.dev', 16 | apiVersion: 'v1alpha1', 17 | kind: 'EventListener', 18 | }; 19 | 20 | export const PipelineRunModel: K8sKind = { 21 | apiGroup: 'tekton.dev', 22 | apiVersion: 'v1beta1', 23 | kind: 'PipelineRun', 24 | }; 25 | 26 | export const TaskRunModel: K8sKind = { 27 | apiGroup: 'tekton.dev', 28 | apiVersion: 'v1beta1', 29 | kind: 'TaskRun', 30 | }; 31 | 32 | export const TaskModel: K8sKind = { 33 | apiGroup: 'tekton.dev', 34 | apiVersion: 'v1beta1', 35 | kind: 'Task', 36 | }; 37 | 38 | export const ClusterTaskModel: K8sKind = { 39 | apiGroup: 'tekton.dev', 40 | apiVersion: 'v1beta1', 41 | kind: 'ClusterTask', 42 | }; 43 | -------------------------------------------------------------------------------- /src/util/stderrstring.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | export function getStderrString(data: string | Error): string { 7 | if (data instanceof Error) { 8 | return data.message; 9 | } else if ((typeof data === 'string')) { 10 | return data; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/util/telemetry-watch-tekton-resource.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { telemetryLog } from '../telemetry'; 7 | import { pipelineTriggerStatus } from './map-object'; 8 | import { version } from './tknversion'; 9 | import { watchResources } from './watchResources'; 10 | 11 | export async function watchTektonResources(extensionStartUpCheck?: boolean): Promise { 12 | const tknVersion = await version(); 13 | const resourceUidAtStart = {}; 14 | if (tknVersion && (tknVersion?.trigger === undefined || tknVersion.trigger.trim() === 'unknown')) { 15 | pipelineTriggerStatus.set('trigger', false); 16 | } 17 | if (!pipelineTriggerStatus.get('pipeline')) { 18 | const resourceList = ['pipeline', 'pipelinerun', 'taskrun', 'task', 'clustertask', 'pipelineresources']; 19 | if (extensionStartUpCheck) telemetryLog('startUp_watch_tekton_Pipeline_resource', 'startUp Pipeline watch'); 20 | watchResources.watchCommand(resourceList, resourceUidAtStart); 21 | pipelineTriggerStatus.set('pipeline', true); 22 | } 23 | if (!pipelineTriggerStatus.get('trigger') && tknVersion && tknVersion?.trigger !== undefined && tknVersion.trigger.trim() !== 'unknown') { 24 | const resourceList = ['tt', 'tb', 'el', 'ctb']; 25 | if (extensionStartUpCheck) telemetryLog('startUp_watch_tekton_Trigger_resource', 'startUp trigger watch'); 26 | watchResources.watchCommand(resourceList, resourceUidAtStart); 27 | pipelineTriggerStatus.set('trigger', true); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/util/tknversion.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { Command } from '../cli-command'; 7 | import { tkn } from '../tkn'; 8 | 9 | 10 | export interface TknVersion { 11 | trigger?: string; 12 | tkn?: string; 13 | pipeline?: string; 14 | } 15 | 16 | const versionType = { 17 | 'Triggers version': 'trigger', 18 | 'Client version': 'tkn', 19 | 'Pipeline version': 'pipeline' 20 | } 21 | 22 | export const tektonVersionType = { 23 | 'trigger': 'Triggers version', 24 | 'tkn': 'Client version', 25 | 'pipeline': 'Pipeline version' 26 | } 27 | 28 | export async function version(): Promise { 29 | const result = await tkn.execute(Command.printTknVersion(), process.cwd(), false); 30 | if (result.error) { 31 | return null; 32 | } 33 | return getVersion(result.stdout); 34 | } 35 | 36 | export function getVersion(tektonVersion: string): TknVersion { 37 | const tknVersion = {}; 38 | const version = new RegExp('^(Triggers version|Client version|Pipeline version):\\s[v]?(unknown|[0-9]+\\.[0-9]+\\.[0-9]+)$'); 39 | if (tektonVersion) { 40 | tektonVersion.trim().split('\n').filter((value) => { 41 | if (value.match(version)) { 42 | tknVersion[versionType[value.match(version)[1]]] = value.match(version)[2]; 43 | } 44 | }); 45 | return tknVersion; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/util/watch.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | 'use strict'; 7 | 8 | import * as fs from 'fs'; 9 | import * as fsex from 'fs-extra'; 10 | import * as path from 'path'; 11 | import { EventEmitter } from 'events'; 12 | import byline = require('byline'); 13 | 14 | export class WatchUtil { 15 | static watchFileForContextChange(location: string, filename: string): FileContentChangeNotifier { 16 | const emitter: EventEmitter = new EventEmitter(); 17 | let timer: NodeJS.Timer; 18 | let context = ''; 19 | fsex.ensureDirSync(location); 20 | const watcher: fs.FSWatcher = fsex.watch(location, (eventType, changedFile) => { 21 | if (filename === changedFile) { 22 | if (timer) { 23 | clearTimeout(timer); 24 | } 25 | 26 | timer = setTimeout(async () => { 27 | timer = undefined; 28 | const newContext = await WatchUtil.grep(path.join(location, filename), /current-context:.*/); 29 | if (context !== newContext) { 30 | emitter.emit('file-changed'); 31 | context = newContext; 32 | } 33 | }, 500); 34 | 35 | } 36 | }); 37 | return { watcher, emitter }; 38 | } 39 | 40 | static grep(fileLocation: string, rx: RegExp): Promise { 41 | return new Promise((resolve, reject) => { 42 | const fileStream = fs.createReadStream(fileLocation, { encoding: 'utf8' }); 43 | byline(fileStream) 44 | .on('data', (line: string) => { 45 | if (rx.test(line)) { 46 | fileStream.close(); 47 | resolve(line); 48 | } 49 | }) 50 | .on('error', reject) 51 | .on('end', resolve); 52 | }); 53 | } 54 | } 55 | 56 | export interface FileContentChangeNotifier { 57 | readonly watcher: fs.FSWatcher; 58 | readonly emitter: EventEmitter; 59 | } 60 | -------------------------------------------------------------------------------- /src/util/windowUtils.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | 'use strict'; 7 | 8 | import { window, Terminal, TerminalOptions } from 'vscode'; 9 | import * as path from 'path'; 10 | 11 | export class WindowUtil { 12 | 13 | static createTerminal(name: string, cwd: string, toolLocation?: string, env: NodeJS.ProcessEnv = process.env): Terminal { 14 | const finalEnv: NodeJS.ProcessEnv = {}; 15 | Object.assign(finalEnv, env); 16 | const key = process.platform === 'win32' ? 'Path' : 'PATH'; 17 | 18 | if (toolLocation && env[key] && !env[key].includes(toolLocation)) { 19 | finalEnv[key] = `${toolLocation}${path.delimiter}${env[key]}`; 20 | } 21 | const options: TerminalOptions = { 22 | cwd: cwd, 23 | name: name, 24 | env: finalEnv 25 | }; 26 | return window.createTerminal(options); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/webview/bundle/App.tsx: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | 7 | import * as React from 'react'; 8 | import { Form } from './Form'; 9 | 10 | // eslint-disable-next-line @typescript-eslint/explicit-function-return-type 11 | export default function App() { 12 | return ( 13 |
14 |
15 |
16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/webview/bundle/bundle.style.tsx: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { Theme, createStyles } from '@material-ui/core/styles'; 7 | 8 | // eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/no-unused-vars 9 | export default (theme: Theme) => 10 | createStyles({ 11 | root: { 12 | '& .MuiFormLabel-root': { 13 | color: 'var(--vscode-disabledForeground)', 14 | }, 15 | }, 16 | button: { 17 | textAlign: 'center', 18 | overflow: 'hidden', 19 | textOverflow: 'ellipsis', 20 | color: 'var(--vscode-button-foreground)', 21 | '&:hover' :{ 22 | backgroundColor: '\'#BE0000\' !important', 23 | }, 24 | '&:focus': { 25 | backgroundColor: '\'#BE0000\' !important', 26 | }, 27 | '&:disabled' :{ 28 | opacity: '0.6', 29 | background: '\'#BE0000\' !important', 30 | }, 31 | }, 32 | inputLabel: { 33 | '&.shrink': { 34 | color: 'var(--vscode-keybindingLabel-foreground)' 35 | } 36 | }, 37 | autocompleteLabel: { 38 | '& .MuiInputLabel-outlined:not(.MuiInputLabel-shrink)': { 39 | color: 'var(--vscode-keybindingLabel-foreground)' 40 | }, 41 | '&.Mui-focused .MuiInputLabel-outlined': { 42 | color: 'var(--vscode-keybindingLabel-foreground)' 43 | } 44 | }, 45 | }) 46 | -------------------------------------------------------------------------------- /src/webview/bundle/form-components/FormInputProps.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | /* eslint-disable @typescript-eslint/no-explicit-any */ 7 | 8 | 9 | export interface FormInputProps { 10 | name?: string; 11 | control?: any; 12 | label?: string; 13 | setValue?: any; 14 | getValue?: any; 15 | placeHolder?: string; 16 | requiredField?: boolean; 17 | fieldType?: string; 18 | } 19 | -------------------------------------------------------------------------------- /src/webview/bundle/form-components/customChip.tsx: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import * as React from 'react'; 7 | import Chip from '@material-ui/core/Chip'; 8 | import makeStyles from '@material-ui/core/styles/makeStyles'; 9 | 10 | 11 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 12 | const useStyles = makeStyles((theme) => ({ 13 | label: { 14 | color: 'black', 15 | } 16 | })); 17 | 18 | // eslint-disable-next-line @typescript-eslint/explicit-function-return-type 19 | export const MyChip = (props) => { 20 | const classes = useStyles(); 21 | return ( 22 | 29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /src/webview/bundle/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | 15 | .MuiSvgIcon-root { 16 | color: var(--vscode-keybindingLabel-foreground); 17 | } 18 | 19 | .css-1kxbtff-MuiAutocomplete-root .MuiAutocomplete-tag { 20 | color: var(--vscode-keybindingLabel-foreground); 21 | } -------------------------------------------------------------------------------- /src/webview/bundle/index.tsx: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import * as React from 'react'; 7 | import * as ReactDOM from 'react-dom'; 8 | import './index.css'; 9 | import App from './App'; 10 | 11 | declare const acquireVsCodeApi: () => ({ getState(): {tektonType: string, name: string}[]; setState(data: {tektonType: string, name: string}[]): void; postMessage: (msg: unknown) => void }); 12 | export const vscode = acquireVsCodeApi(); 13 | 14 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 15 | const rootElement: any = document.getElementById('root'); 16 | 17 | window.addEventListener('message', event => { 18 | switch (event.data.type) { 19 | case 'tekton_bundle': 20 | vscode.setState(event.data.data); 21 | ReactDOM.render( 22 | , 23 | rootElement 24 | ); 25 | } 26 | }); 27 | 28 | const previousState = vscode.getState(); 29 | if (previousState) { 30 | ReactDOM.render( 31 | , 32 | rootElement 33 | ); 34 | } 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/webview/bundle/style.scss: -------------------------------------------------------------------------------- 1 | .buttonStyle { 2 | text-align: center; 3 | overflow: hidden; 4 | text-overflow: ellipsis; 5 | color: var(--vscode-button-foreground); 6 | 7 | &:hover { 8 | background-color: '#BE0000' !important; 9 | } 10 | 11 | text-transform: none; 12 | } 13 | 14 | .mainContainer, 15 | .formContainer, 16 | .form { 17 | display: flex; 18 | flex-direction: column; 19 | font-family: var(--vscode-font-family); 20 | // overflow-y: scroll; 21 | } 22 | 23 | .margin { 24 | margin: 1% 1% 1% 3%; 25 | } 26 | 27 | .title { 28 | width: 100%; 29 | margin-bottom: 1%; 30 | } 31 | 32 | .subTitle { 33 | margin-bottom: 3%; 34 | max-width: 81%; 35 | justify-content: center; 36 | word-spacing: 5px; 37 | text-align: justify; 38 | color: var(--vscode-foreground); 39 | font-weight: normal; 40 | font-size: 14px; 41 | } 42 | -------------------------------------------------------------------------------- /src/webview/common/dom-util.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | export function createDiv(...className: string[]): HTMLDivElement { 7 | const element = document.createElement('div'); 8 | if (className){ 9 | element.classList.add(...className); 10 | } 11 | return element; 12 | } 13 | 14 | export function createDivWithID(className: string, id?: string): HTMLDivElement { 15 | const element = document.createElement('div'); 16 | if (className) element.classList.add(className); 17 | if (id) element.id = id; 18 | return element; 19 | } 20 | 21 | export function createSpan(...classNames: string[]): HTMLSpanElement { 22 | const element = document.createElement('span'); 23 | if (classNames){ 24 | element.classList.add(...classNames); 25 | } 26 | return element; 27 | } 28 | -------------------------------------------------------------------------------- /src/webview/common/loader.css: -------------------------------------------------------------------------------- 1 | .progress { 2 | justify-content: flex-start; 3 | align-items: center; 4 | position: relative; 5 | padding: 0 5px; 6 | display: flex; 7 | height: 2px; 8 | width: 100%; 9 | display: none; 10 | } 11 | 12 | .progress-value { 13 | background: var(--vscode-progressBar-background); 14 | transition: width 100ms linear; 15 | animation-name: progress; 16 | animation-duration: 4s; 17 | animation-iteration-count: infinite; 18 | animation-timing-function: linear; 19 | transform: translate3d(0px, 0px, 0px); 20 | height: 2px; 21 | width: 2%; 22 | } 23 | 24 | @keyframes progress { from { transform: translateX(0%) scaleX(1) } 50% { transform: translateX(2500%) scaleX(3) } to { transform: translateX(4900%) scaleX(1) } } 25 | -------------------------------------------------------------------------------- /src/webview/common/loader.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { createDiv } from './dom-util'; 7 | import { BaseWidget } from './widget'; 8 | import './loader.css'; 9 | 10 | export class Loader extends BaseWidget { 11 | constructor() { 12 | super(); 13 | this.element = createDiv('progress'); 14 | const value = createDiv('progress-value'); 15 | this.element.appendChild(value); 16 | this.hide(); 17 | } 18 | 19 | hide(): void { 20 | this.element.style.display = 'none'; 21 | } 22 | 23 | show(): void { 24 | this.element.style.display = 'block'; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/webview/common/reset.css: -------------------------------------------------------------------------------- 1 | html { 2 | box-sizing: border-box; 3 | font-size: 13px; 4 | } 5 | 6 | *, 7 | *:before, 8 | *:after { 9 | box-sizing: inherit; 10 | } 11 | 12 | body, 13 | h1, 14 | h2, 15 | h3, 16 | h4, 17 | h5, 18 | h6, 19 | p, 20 | ol, 21 | ul { 22 | margin: 0; 23 | padding: 0; 24 | font-weight: normal; 25 | } 26 | 27 | img { 28 | max-width: 100%; 29 | height: auto; 30 | } 31 | -------------------------------------------------------------------------------- /src/webview/common/vscode-api.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | export interface ViewState { 7 | getState(): unknown; 8 | setState(data: unknown): void; 9 | } 10 | 11 | export interface VSMessage { 12 | postMessage: (msg: Message) => void; 13 | } 14 | 15 | export interface Message { 16 | type: string; 17 | data?: unknown; 18 | } 19 | -------------------------------------------------------------------------------- /src/webview/common/widget.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | export type Listener = (item: T) => void; 7 | 8 | 9 | export interface Widget { 10 | getElement(): HTMLElement; 11 | } 12 | 13 | export class BaseWidget implements Widget { 14 | protected element: HTMLElement; 15 | 16 | getElement(): HTMLElement { 17 | return this.element; 18 | } 19 | 20 | clear(): void { 21 | if (this.element){ 22 | this.element.innerHTML = ''; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/webview/hub/custom.d.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | declare module '*.svg' { 6 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 7 | const content: any; 8 | export default content; 9 | } 10 | -------------------------------------------------------------------------------- /src/webview/hub/index.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import '../common/reset.css'; 7 | import '../common/vscode.css'; 8 | import 'vscode-codicons/dist/codicon.css'; 9 | import * as api from '../../tekton-hub-client/index'; 10 | import { ViewState, VSMessage } from '../common/vscode-api'; 11 | import { ResourceView } from './resource-view'; 12 | 13 | declare const acquireVsCodeApi: () => ViewState & VSMessage; 14 | export const vscode = acquireVsCodeApi(); 15 | 16 | const view = new ResourceView(vscode); 17 | window.addEventListener('message', event => { 18 | switch (event.data.type) { 19 | case 'showTasks':{ 20 | const tasks: api.ResourceData[] = event.data.data; 21 | view.showTasks(tasks); 22 | break; 23 | } 24 | case 'error': 25 | view.setErrorState(event.data.data); 26 | break; 27 | case 'tknVersion': 28 | view.setTknVersion(event.data.data); 29 | break; 30 | case 'installedResources': 31 | view.setInstalledResources(event.data.data); 32 | break; 33 | case 'recommendedTasks': 34 | view.setRecommendedTasks(event.data.data); 35 | break; 36 | case 'cancelInstall': 37 | view.cancelInstall(); 38 | break; 39 | default: 40 | console.error(`Cannot handle: ${JSON.stringify(event.data)}`); 41 | 42 | } 43 | }, false); 44 | 45 | vscode.postMessage({type: 'ready'}); 46 | -------------------------------------------------------------------------------- /src/webview/hub/pipeline.svg: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /src/webview/pipeline-preview/popup.css: -------------------------------------------------------------------------------- 1 | .popup-container { 2 | border: 1px solid var(--vscode-focusBorder); 3 | background-color: var(--vscode-input-background); 4 | padding: 3px; 5 | border-radius: 4px; 6 | } 7 | 8 | .steps-container { 9 | margin: 0; 10 | padding-left: 20px; 11 | } 12 | -------------------------------------------------------------------------------- /src/webview/pipeline/app/utils/const.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | 7 | export enum VolumeTypes { 8 | EmptyDirectory = 'Empty Directory', 9 | ConfigMap = 'Config Map', 10 | Secret = 'Secret', 11 | PersistentVolumeClaim = 'PVC', 12 | } 13 | 14 | export const initialResourceFormValues = { 15 | name: undefined, 16 | params: [], 17 | resources: [], 18 | workspaces: [], 19 | trigger: undefined, 20 | newPvc: [], 21 | newPipelineResource: [], 22 | serviceAccount: undefined, 23 | commandId: undefined, 24 | volumeClaimTemplate: [] 25 | } 26 | 27 | export enum WorkspaceOption { 28 | emptyDirectory = 'EmptyDirectory', 29 | configMap = 'ConfigMap', 30 | secret = 'Secret', 31 | persistentVolumeClaim = 'PersistentVolumeClaim', 32 | } 33 | 34 | export const volumeClaimTemplate = 'Create a new VolumeClaimTemplate'; 35 | 36 | export const volumeClaimTemplateID = 'create-new-VolumeClaimTemplate-entry'; 37 | 38 | export enum TknResourceType { 39 | Trigger = 'Webhook', 40 | Params = 'Parameters', 41 | GitResource = 'Git Resource', 42 | ImageResource = 'Image Resource', 43 | Workspaces = 'Workspaces', 44 | ServiceAccountName = 'Service Account Name' 45 | } 46 | 47 | export enum typeOfResource { 48 | git = 'git', 49 | image = 'image' 50 | } 51 | 52 | export enum workspaceResource { 53 | Secret = 'secret', 54 | ConfigMap = 'configMap', 55 | PersistentVolumeClaim = 'persistentVolumeClaim' 56 | } 57 | 58 | export enum workspaceResourceTypeName { 59 | Secret = 'secretName', 60 | ConfigMap = 'name', 61 | PersistentVolumeClaim = 'claimName' 62 | } 63 | 64 | export const accessMode = [ 65 | { 66 | name: 'Single User (RWO)', 67 | value: 'ReadWriteOnce' 68 | }, 69 | { 70 | name: 'Shared Access (RWX)', 71 | value: 'ReadWriteMany' 72 | }, 73 | { 74 | name: 'Read Only (ROX)', 75 | value: 'ReadOnlyMany' 76 | } 77 | ] 78 | 79 | export const size = [ 80 | { 81 | name: 'MiB', 82 | value: 'Mi' 83 | }, 84 | { 85 | name: 'GiB', 86 | value: 'Gi' 87 | }, 88 | { 89 | name: 'TiB', 90 | value: 'Ti' 91 | } 92 | ]; 93 | -------------------------------------------------------------------------------- /src/webview/pipeline/app/utils/util.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | export function selectText(nodeList: NodeListOf, text?: string, selected?: boolean, id?: string): void { 7 | nodeList.forEach(element => { 8 | const resourceSelectList = element.childNodes; 9 | const op = document.createElement('option'); 10 | op.value = text; 11 | op.text = text; 12 | op.id = id ?? ''; 13 | op.selected = selected ?? false; 14 | resourceSelectList.forEach(selectElement => { 15 | selectElement.insertBefore(op, selectElement.firstChild); 16 | }); 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /src/webview/pipeline/app/widgets/navigation.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { createDiv } from '../../../common/dom-util'; 7 | import { BaseWidget, Listener } from '../../../common/widget'; 8 | 9 | export class NavigationItem extends BaseWidget { 10 | constructor(name: string) { 11 | super(); 12 | this.element = createDiv('navigationItem'); 13 | this.element.innerText = name; 14 | this.element.title = name; 15 | } 16 | 17 | setSelected(): void { 18 | this.element.classList.add('navigationItem-selected'); 19 | } 20 | 21 | removeSelection(): void { 22 | this.element.classList.remove('navigationItem-selected'); 23 | } 24 | } 25 | 26 | export class NavigationList extends BaseWidget { 27 | 28 | private selectedItem: NavigationItem; 29 | 30 | private selectionListener: Listener; 31 | 32 | constructor() { 33 | super(); 34 | this.element = document.createElement('div'); 35 | this.element.className = 'navigation'; 36 | } 37 | 38 | addItem(item: NavigationItem): void { 39 | this.element.appendChild(item.getElement()); 40 | item.getElement().onclick = (() => { 41 | console.log(JSON.stringify(this)); 42 | this.selectItem(item); 43 | if (this.selectionListener) { 44 | this.selectionListener(item); 45 | } 46 | }); 47 | } 48 | 49 | selectItem(item: NavigationItem): void { 50 | if (this.selectedItem == item) { 51 | return; 52 | } 53 | 54 | if (this.selectedItem) { 55 | this.selectedItem.removeSelection(); 56 | } 57 | item.setSelected(); 58 | this.selectedItem = item; 59 | } 60 | 61 | setSelectionListener(listener: Listener): void { 62 | this.selectionListener = listener; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/webview/resource-page/index.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import '../common/reset.css'; 7 | import '../common/vscode.css'; 8 | import 'vscode-codicons/dist/codicon.css'; 9 | import { ViewState, VSMessage } from '../common/vscode-api'; 10 | import { TaskWidget } from './resource-widget'; 11 | 12 | 13 | declare const acquireVsCodeApi: () => ViewState & VSMessage; 14 | export const vscode = acquireVsCodeApi(); 15 | 16 | const rootElement = document.getElementById('root'); 17 | const widget = new TaskWidget(rootElement, vscode); 18 | 19 | window.addEventListener('message', event => { 20 | switch (event.data.type) { 21 | case 'showTask': 22 | widget.showTask(event.data.data.task, event.data.data.tknVersion); 23 | break; 24 | case 'setVersions': 25 | widget.setVersions(event.data.data); 26 | break; 27 | case 'taskVersion': 28 | widget.setTaskVersion(event.data.data); 29 | break; 30 | case 'cancelInstall': 31 | widget.cancelInstall(); 32 | break; 33 | default: 34 | console.error(`Cannot handle: ${JSON.stringify(event.data)}`); 35 | } 36 | }, false); 37 | 38 | 39 | vscode.postMessage({type: 'ready'}); 40 | -------------------------------------------------------------------------------- /src/webview/resource-page/yaml-highlight.css: -------------------------------------------------------------------------------- 1 | .code-line-numbers__number { 2 | color: var(--vscode-editorLineNumber-foreground); 3 | background-color:var(--vscode-editor-background); 4 | padding: 0px 10px; 5 | margin-right: 5px; 6 | line-height: var(--vscode-editor-font-size); 7 | } 8 | 9 | .code-line-numbers__number__zeros { 10 | color: transparent; 11 | } 12 | 13 | .language-yaml { 14 | display: block; 15 | overflow-x: auto; 16 | padding: 0.5em; 17 | } 18 | 19 | .hljs-keyword, 20 | .hljs-selector-tag, 21 | .hljs-literal, 22 | .hljs-section, 23 | .hljs-link { 24 | color: white; 25 | } 26 | 27 | .hljs, 28 | .hljs-subst { 29 | color: #ddd; 30 | } 31 | 32 | .hljs-string, 33 | .hljs-title, 34 | .hljs-name, 35 | .hljs-type, 36 | .hljs-symbol, 37 | .hljs-bullet, 38 | .hljs-built_in, 39 | .hljs-addition, 40 | .hljs-variable, 41 | .hljs-template-tag, 42 | .hljs-template-variable { 43 | color: var(--vscode-debugTokenExpression-string); 44 | } 45 | 46 | .hljs-comment, 47 | .hljs-quote, 48 | .hljs-deletion, 49 | .hljs-meta { 50 | color: var(--vscode-debugTokenExpression-number); 51 | } 52 | 53 | .hljs-keyword, 54 | .hljs-selector-tag, 55 | .hljs-literal, 56 | .hljs-title, 57 | .hljs-section, 58 | .hljs-doctag, 59 | .hljs-type, 60 | .hljs-name, 61 | .hljs-strong { 62 | font-weight: bold; 63 | } 64 | 65 | .hljs-emphasis { 66 | font-style: italic; 67 | } 68 | 69 | .hljs-attr, 70 | .hljs-attribute { 71 | color: var(--vscode-debugView-valueChangedHighlight); 72 | } 73 | -------------------------------------------------------------------------------- /src/yaml-support/snippet.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | export interface Snippet { 7 | label: string; 8 | description?: string; 9 | body: T; 10 | } 11 | -------------------------------------------------------------------------------- /src/yaml-support/tkn-editing.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import * as vscode from 'vscode'; 7 | import { Disposable } from '../util/disposable'; 8 | import { codeActionProvider } from './tkn-code-actions'; 9 | import { definitionProvider, definitionProviderMap } from './tkn-definition-providers'; 10 | import { tektonYaml } from './tkn-yaml'; 11 | 12 | const disposable = new Disposable(); 13 | 14 | const langFuncMap = new Map(); 15 | 16 | export function initializeTknEditing(context: vscode.ExtensionContext): void { 17 | context.subscriptions.push(disposable); 18 | vscode.workspace.textDocuments.forEach(handleTextDocument); 19 | disposable.register(vscode.workspace.onDidOpenTextDocument(handleTextDocument)); 20 | disposable.register(vscode.workspace.onDidCloseTextDocument(doc => { 21 | if (langFuncMap.has(doc.uri.fsPath)){ 22 | langFuncMap.get(doc.uri.fsPath).dispose(); 23 | langFuncMap.delete(doc.uri.fsPath); 24 | } 25 | })); 26 | disposable.register({ 27 | dispose: ()=> { 28 | langFuncMap.forEach(it => it.dispose()); 29 | }}); 30 | } 31 | 32 | function handleTextDocument(doc: vscode.TextDocument): void { 33 | if (doc.languageId === 'yaml') { 34 | const type = tektonYaml.isTektonYaml(doc); 35 | if (!langFuncMap.has(doc.uri.fsPath)){ 36 | langFuncMap.set(doc.uri.fsPath, new Disposable()); 37 | } 38 | if (type && definitionProviderMap.has(type)) { 39 | langFuncMap.get(doc.uri.fsPath).register(vscode.languages.registerDefinitionProvider({ language: 'yaml', pattern: doc.fileName }, definitionProvider)) 40 | } 41 | 42 | if (type && codeActionProvider.isSupports(type)){ 43 | langFuncMap.get(doc.uri.fsPath).register( 44 | vscode.languages.registerCodeActionsProvider({language: 'yaml', pattern: doc.fileName}, codeActionProvider.getProvider(type), codeActionProvider.getProviderMetadata(type))); 45 | } 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/yaml-support/tkn-scheme-storage.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | import * as vscode from 'vscode'; 6 | 7 | interface TknSchemeCacheItem { 8 | scheme: string; 9 | version: number; 10 | } 11 | 12 | export interface SchemeGenerator { 13 | (vsDocument: vscode.TextDocument): Promise; 14 | } 15 | 16 | export class TknSchemeStorage { 17 | 18 | private cache: { [key: string]: TknSchemeCacheItem } = {}; 19 | 20 | async getScheme(vsDocument: vscode.TextDocument, generator: SchemeGenerator): Promise { 21 | const key = vsDocument.uri.toString(); 22 | await this.ensureCache(key, vsDocument, generator); 23 | return this.cache[key].scheme; 24 | } 25 | 26 | private async ensureCache(key: string, doc: vscode.TextDocument, generator: SchemeGenerator): Promise { 27 | if (!this.cache[key]) { 28 | this.cache[key] = { version: -1 } as TknSchemeCacheItem; 29 | } 30 | 31 | if (this.cache[key].version !== doc.version) { 32 | try { 33 | const scheme = await generator(doc); 34 | this.cache[key].scheme = scheme; 35 | this.cache[key].version = doc.version; 36 | } catch (err) { 37 | console.error(err); 38 | } 39 | 40 | } 41 | } 42 | } 43 | 44 | const schemeStorage = new TknSchemeStorage(); 45 | 46 | export { schemeStorage }; 47 | -------------------------------------------------------------------------------- /test/debugger/debugExplorer.test.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import * as chai from 'chai'; 7 | import * as sinonChai from 'sinon-chai'; 8 | import sinon = require('sinon'); 9 | import { DebugExplorer } from '../../src/debugger/debugExplorer'; 10 | import { debugSessions } from '../../src/util/map-object'; 11 | 12 | const expect = chai.expect; 13 | chai.use(sinonChai); 14 | 15 | suite('Tekton Application Explorer', () => { 16 | let tektonInstance: DebugExplorer; 17 | const sandbox = sinon.createSandbox(); 18 | 19 | setup(() => { 20 | tektonInstance = new DebugExplorer(); 21 | sandbox.stub(debugSessions, 'size').returns(1); 22 | }); 23 | 24 | teardown(() => { 25 | sandbox.restore(); 26 | }); 27 | 28 | test('delegate calls to TektonObject instance', async () => { 29 | debugSessions.set('test', {}); 30 | const pipelineNodes = await tektonInstance.getChildren(); 31 | expect(pipelineNodes.length).equals(1); 32 | debugSessions.delete('test'); 33 | }); 34 | 35 | test('return null if no tree item found', async () => { 36 | const pipelineNodes = await tektonInstance.getTreeItem(null); 37 | expect(pipelineNodes).equals(null); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /test/debugger/show-in-terminal.test.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | 'use strict'; 7 | 8 | import * as chai from 'chai'; 9 | import * as sinonChai from 'sinon-chai'; 10 | import * as sinon from 'sinon'; 11 | import { TknImpl } from '../../src/tkn'; 12 | import * as vscode from 'vscode'; 13 | import * as tkn from '../../src/tkn'; 14 | import { ContextType } from '../../src/context-type'; 15 | import * as telemetry from '../../src/telemetry'; 16 | import { TestItem } from '../tekton/testTektonitem'; 17 | import { Command } from '../../src/cli-command'; 18 | import { openContainerInTerminal } from '../../src/debugger/show-in-terminal'; 19 | import { debugSessions } from '../../src/util/map-object'; 20 | 21 | const expect = chai.expect; 22 | chai.use(sinonChai); 23 | 24 | suite('debug/TaskRunContinue', () => { 25 | const sandbox = sinon.createSandbox(); 26 | let executeInTerminalStub: sinon.SinonStub; 27 | const taskRunNode = new TestItem(TknImpl.ROOT, 'test-task-run', ContextType.TASKRUN, null); 28 | 29 | setup(() => { 30 | sandbox.stub(telemetry, 'telemetryLog'); 31 | executeInTerminalStub = sandbox.stub(tkn.tkn, 'executeInTerminal'); 32 | }); 33 | 34 | teardown(() => { 35 | sandbox.restore(); 36 | }); 37 | 38 | suite('Debug Fail Continue TaskRun', () => { 39 | 40 | test('return null if no taskRun found', async () => { 41 | const result = await openContainerInTerminal(null); 42 | expect(result).equals(null); 43 | }); 44 | 45 | test('Debug and fail continue taskRun', async () => { 46 | sandbox.stub(debugSessions, 'get').returns({containerName: 'test-task-run', podName: 'test', namespace: 'test'}); 47 | sandbox.stub(vscode.window, 'terminals').resolves([{name: 'Tekton:test-task-run'}]); 48 | await openContainerInTerminal(taskRunNode); 49 | expect(executeInTerminalStub).calledOnceWith(Command.loginToContainer('test-task-run', 'test', 'test')); 50 | }); 51 | 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /test/fixtures/test.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/test/fixtures/test.gz -------------------------------------------------------------------------------- /test/fixtures/test.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/test/fixtures/test.tar.gz -------------------------------------------------------------------------------- /test/fixtures/test.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/vscode-tekton/b9543d32d904f0a335501002a35bdf3a47f90158/test/fixtures/test.zip -------------------------------------------------------------------------------- /test/model/pipeline/pipeline-with-finally.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: clone-cleanup-workspace 5 | spec: 6 | workspaces: 7 | # common workspace where git repo is cloned and needs to be cleanup after done 8 | - name: git-source 9 | tasks: 10 | # Clone app repo to workspace 11 | - name: clone-app-repo 12 | taskRef: 13 | name: git-clone-from-catalog 14 | params: 15 | - name: url 16 | value: https://github.com/tektoncd/community.git 17 | - name: subdirectory 18 | value: application 19 | workspaces: 20 | - name: output 21 | workspace: git-source 22 | finally: 23 | # Cleanup workspace 24 | - name: cleanup 25 | taskRef: 26 | name: cleanup-workspace 27 | workspaces: 28 | - name: source 29 | workspace: git-source 30 | -------------------------------------------------------------------------------- /test/model/pipeline/pipeline.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: tutorial-pipeline 5 | spec: 6 | resources: 7 | - name: source-repo 8 | type: git 9 | optional: true 10 | - name: web-image 11 | type: image 12 | tasks: 13 | - name: build-skaffold-web 14 | taskRef: 15 | name: build-docker-image-from-git-source 16 | params: 17 | - name: pathToDockerFile 18 | value: Dockerfile 19 | - name: pathToContext 20 | value: /workspace/docker-source/examples/microservices/leeroy-web #configure: may change according to your source 21 | resources: 22 | inputs: 23 | - name: docker-source 24 | resource: source-repo 25 | outputs: 26 | - name: builtImage 27 | resource: web-image 28 | - name: deploy-web 29 | taskRef: 30 | name: deploy-using-kubectl 31 | resources: 32 | inputs: 33 | - name: source 34 | resource: source-repo 35 | - name: image 36 | resource: web-image 37 | from: 38 | - build-skaffold-web 39 | params: 40 | - name: path 41 | value: /workspace/source/examples/microservices/leeroy-web/kubernetes/deployment.yaml #configure: may change according to your source 42 | - name: yamlPathToImage 43 | value: "spec.template.spec.containers[0].image" 44 | -------------------------------------------------------------------------------- /test/pipeline/pipeline-preview.test.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | 7 | import * as vscode from 'vscode'; 8 | import * as sinon from 'sinon'; 9 | import * as chai from 'chai'; 10 | import * as sinonChai from 'sinon-chai'; 11 | import { tektonYaml } from '../../src/yaml-support/tkn-yaml'; 12 | import * as preview from '../../src/pipeline/preview-manager'; 13 | import { showPipelinePreview } from '../../src/pipeline/pipeline-preview'; 14 | import { TektonYamlType } from '../../src/yaml-support/tkn-yaml'; 15 | import { pipelineGraph } from '../../src/pipeline/pipeline-graph'; 16 | 17 | const expect = chai.expect; 18 | chai.use(sinonChai); 19 | 20 | suite('pipeline preview', () => { 21 | const sandbox = sinon.createSandbox(); 22 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 23 | let activeEditor: any; 24 | let tknDocuments: sinon.SinonStub; 25 | let previewManager: sinon.SinonStub; 26 | 27 | setup(() => { 28 | activeEditor = {} as vscode.TextEditor; 29 | sandbox.stub(vscode.window, 'activeTextEditor').value(activeEditor); 30 | tknDocuments = sandbox.stub(tektonYaml, 'getTektonDocuments'); 31 | previewManager = sandbox.stub(preview.previewManager, 'showPipelinePreview'); 32 | }); 33 | 34 | teardown(() => { 35 | sandbox.restore(); 36 | }); 37 | 38 | 39 | test('showPipelinePreview() should check yaml documents', () => { 40 | const doc = sandbox.mock(); 41 | activeEditor.document = doc; 42 | showPipelinePreview(); 43 | expect(tknDocuments.calledTwice).true 44 | expect(tknDocuments.calledWith(doc, TektonYamlType.Pipeline)).true; 45 | }); 46 | 47 | test('showPipelinePreview() should calls "previewManager.showPipelinePreview"', () => { 48 | const doc = sandbox.mock(); 49 | activeEditor.document = doc; 50 | tknDocuments.returns([{}]); 51 | 52 | showPipelinePreview(); 53 | expect(previewManager).calledOnceWith(doc, { resourceColumn: vscode.ViewColumn.One, previewColumn: vscode.ViewColumn.One + 1, graphProvider: pipelineGraph }); 54 | }); 55 | 56 | }); 57 | -------------------------------------------------------------------------------- /test/single-test-run.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import * as path from 'path'; 7 | import Mocha = require('mocha'); 8 | 9 | // Linux: prevent a weird NPE when mocha on Linux requires the window size from the TTY 10 | // Since we are not running in a tty environment, we just implement the method statically 11 | // eslint-disable-next-line @typescript-eslint/no-var-requires 12 | const tty = require('tty'); 13 | if (!tty.getWindowSize) { 14 | tty.getWindowSize = (): number[] => { 15 | return [80, 75]; 16 | }; 17 | } 18 | 19 | // eslint-disable-next-line @typescript-eslint/ban-types 20 | const config: {} = { 21 | ui: 'tdd', 22 | timeout: 15000, 23 | color: true, 24 | fullStackTrace: true, 25 | }; 26 | 27 | const mocha = new Mocha(config); 28 | 29 | // eslint-disable-next-line @typescript-eslint/ban-types 30 | export function run(testsRoots: string, cb: (error: {}, failures?: number) => void): void { 31 | 32 | const testsRoot = path.resolve(__dirname); 33 | const testFile = process.env.VSCODE_SINGLE_TEST; 34 | 35 | if (!testFile) { 36 | cb('Cannot find tests'); 37 | return; 38 | } 39 | if (path.extname(testFile) !== '.ts') { 40 | cb(`Cannot run test from: ${testFile}`); 41 | return; 42 | } 43 | 44 | const nFileName = path.basename(testFile, path.extname(testFile)) + '.js'; 45 | const pathSegments = testFile.split(path.sep); 46 | 47 | 48 | mocha.addFile(path.join(testsRoot, ...pathSegments.slice(1, -1), nFileName)); 49 | 50 | try { 51 | mocha.run(failures => { 52 | setTimeout(() => { 53 | if (failures > 0) { 54 | cb(new Error(`${failures} tests failed.`)); 55 | } else { 56 | cb(null, failures); 57 | } 58 | }, 100); 59 | }); 60 | 61 | } catch (err) { 62 | console.error(err); 63 | cb(err); 64 | } 65 | 66 | } 67 | 68 | -------------------------------------------------------------------------------- /test/tekton/task.test.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | 'use strict'; 7 | 8 | import * as chai from 'chai'; 9 | import * as sinonChai from 'sinon-chai'; 10 | import * as sinon from 'sinon'; 11 | import { TknImpl } from '../../src/tkn'; 12 | import { TektonItem } from '../../src/tekton/tektonitem'; 13 | import { TestItem } from './testTektonitem'; 14 | import * as vscode from 'vscode'; 15 | import { ContextType } from '../../src/context-type'; 16 | 17 | // const expect = chai.expect; 18 | chai.use(sinonChai); 19 | 20 | suite('Tekton/Task', () => { 21 | const sandbox = sinon.createSandbox(); 22 | const taskNode = new TestItem(TknImpl.ROOT, 'test-task', ContextType.TASKNODE, null); 23 | const taskItem = new TestItem(taskNode, 'task', ContextType.TASK, null); 24 | 25 | 26 | setup(() => { 27 | sandbox.stub(TknImpl.prototype, 'execute').resolves({ error: null, stdout: '', stderr: '' }); 28 | sandbox.stub(TknImpl.prototype, 'getTasks').resolves([taskItem]); 29 | sandbox.stub(TektonItem, 'getTaskNames').resolves([taskItem]); 30 | sandbox.stub(vscode.window, 'showInputBox').resolves(); 31 | }); 32 | 33 | teardown(() => { 34 | sandbox.restore(); 35 | }); 36 | 37 | }); 38 | -------------------------------------------------------------------------------- /test/tekton/testTektonitem.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import { ContextType } from '../../src/context-type'; 7 | import { TektonNode } from '../../src/tree-view/tekton-node'; 8 | 9 | export class TestItem implements TektonNode { 10 | 11 | 12 | constructor( 13 | private parent: TektonNode, 14 | private name: string, 15 | public readonly contextValue: ContextType, 16 | private children = [], 17 | public creationtime?: string, 18 | public state?: string) { 19 | } 20 | 21 | getName(): string { 22 | return this.name; 23 | } 24 | 25 | getTreeItem(): string { 26 | return null; 27 | } 28 | 29 | getChildren(): TektonNode[] { 30 | return this.children; 31 | } 32 | 33 | getParent(): TektonNode { 34 | return this.parent; 35 | } 36 | 37 | get label(): string { 38 | return this.name; 39 | } 40 | 41 | refresh(): Promise { 42 | return Promise.resolve(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/tkn.int.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import * as vscode from 'vscode'; 7 | import * as tkn from '../src/tkn'; 8 | import * as assert from 'assert'; 9 | import * as sinon from 'sinon'; 10 | import { TestItem } from './tekton/testTektonitem'; 11 | import { Pipeline } from '../src/tekton/pipeline'; 12 | import { ContextType } from '../src/context-type'; 13 | 14 | suite('tkn integration', () => { 15 | const tk: tkn.Tkn = tkn.tkn; 16 | const pipelineItem = new TestItem(null, 'pipeline', ContextType.PIPELINE); 17 | const sb = sinon.createSandbox(); 18 | 19 | setup(() => { 20 | 21 | sb.stub(vscode.window, 'showInformationMessage').resolves('Download and install'); 22 | }); 23 | 24 | teardown(() => { 25 | sb.restore(); 26 | }); 27 | 28 | suite('explorer', () => { 29 | 30 | test('getPipelines()', async () => { 31 | const pipelines = await tk.getPipelines(pipelineItem); 32 | assert.ok(pipelines.length > 0); 33 | }); 34 | 35 | test('getPipelines()', async () => { 36 | const pipelines = await tk.getPipelines(pipelineItem); 37 | assert.ok(pipelines.length > 0); 38 | }); 39 | 40 | test('about()', async () => { 41 | await Pipeline.about(); 42 | assert.ok(true); 43 | }); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /test/util/platform.test.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | 'use strict'; 7 | 8 | import * as chai from 'chai'; 9 | import * as sinonChai from 'sinon-chai'; 10 | import * as sinon from 'sinon'; 11 | import { Platform } from '../../src/util/platform'; 12 | 13 | const expect = chai.expect; 14 | chai.use(sinonChai); 15 | 16 | suite('Platform Utility', () => { 17 | const sandbox = sinon.createSandbox(); 18 | teardown(() => { 19 | sandbox.restore(); 20 | }); 21 | 22 | test('getOS returns the platform name', () => { 23 | const os = Platform.getOS(); 24 | expect(os).equals(process.platform); 25 | }); 26 | 27 | test('OS delegates to getOS', () => { 28 | const spy = sandbox.spy(Platform, 'getOS'); 29 | const os = Platform.OS; 30 | 31 | expect(spy).calledOnce; 32 | expect(os).equals(process.platform); 33 | }); 34 | 35 | test('getEnv returns the platform environment', () => { 36 | const env = Platform.getEnv(); 37 | expect(env).equals(process.env); 38 | }); 39 | 40 | test('ENV delegates to getENV', () => { 41 | const spy = sandbox.spy(Platform, 'getEnv'); 42 | const env = Platform.ENV; 43 | 44 | expect(spy).calledOnce; 45 | expect(env).equals(process.env); 46 | }); 47 | 48 | test('getUserHomePath returns the path to user home', () => { 49 | const home = Platform.getUserHomePath(); 50 | if (process.platform === 'win32') { 51 | expect(home).equals(process.env.USERPROFILE); 52 | } else { 53 | expect(home).equals(process.env.HOME); 54 | } 55 | }); 56 | }); 57 | -------------------------------------------------------------------------------- /test/util/window.test.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | 'use strict'; 7 | 8 | import * as chai from 'chai'; 9 | import * as sinonChai from 'sinon-chai'; 10 | import * as sinon from 'sinon'; 11 | import * as path from 'path'; 12 | import { window, TerminalOptions } from 'vscode'; 13 | import { WindowUtil } from '../../src/util/windowUtils'; 14 | 15 | const expect = chai.expect; 16 | chai.use(sinonChai); 17 | 18 | suite('Window Utility', () => { 19 | const sandbox = sinon.createSandbox(); 20 | let termStub: sinon.SinonStub; 21 | 22 | setup(() => { 23 | termStub = sandbox.stub(window, 'createTerminal'); 24 | }); 25 | 26 | teardown(() => { 27 | sandbox.restore(); 28 | }); 29 | 30 | test('createTerminal creates a terminal object', () => { 31 | WindowUtil.createTerminal('name', process.cwd()); 32 | expect(termStub).calledOnce; 33 | }); 34 | 35 | test('createTerminal adds tools location and shell path to the environment', () => { 36 | const toolLocationDir = path.dirname(path.join('dir', 'where', 'tool', 'is', 'located', 'tool')); 37 | const env: NodeJS.ProcessEnv = {}; 38 | const key = process.platform === 'win32' ? 'Path' : 'PATH'; 39 | Object.assign(env, process.env); 40 | env[key] = `${toolLocationDir}${path.delimiter}${process.env[key]}`; 41 | 42 | const options: TerminalOptions = { 43 | cwd: process.cwd(), 44 | name: 'terminal', 45 | env: env 46 | }; 47 | WindowUtil.createTerminal('terminal', process.cwd(), toolLocationDir); 48 | 49 | expect(termStub).calledOnceWith(options); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /test/yaml-support/conditional-pipeline.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1alpha1 2 | kind: Pipeline 3 | metadata: 4 | name: conditional-pipeline 5 | spec: 6 | resources: 7 | - name: source-repo 8 | type: git 9 | params: 10 | - name: "path" 11 | default: "README.md" 12 | tasks: 13 | - name: first-create-file 14 | taskRef: 15 | name: create-readme-file 16 | resources: 17 | outputs: 18 | - name: workspace 19 | resource: source-repo 20 | - name: then-check 21 | conditions: 22 | - conditionRef: "file-exists" 23 | params: 24 | - name: "path" 25 | value: "$(params.path)" 26 | resources: 27 | - name: workspace 28 | resource: source-repo 29 | from: [first-create-file] 30 | taskRef: 31 | name: echo-hello 32 | -------------------------------------------------------------------------------- /test/yaml-support/echo-hello-task.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | annotations: 5 | kubectl.kubernetes.io/last-applied-configuration: | 6 | {"apiVersion":"tekton.dev/v1beta1","kind":"Task","metadata":{"annotations":{},"name":"echo-hello","namespace":"default"},"spec":{"steps":[{"image":"ubuntu","name":"echo","script":"echo hello"}]}} 7 | creationTimestamp: "2021-03-03T08:04:56Z" 8 | generation: 1 9 | managedFields: 10 | - apiVersion: tekton.dev/v1beta1 11 | fieldsType: FieldsV1 12 | fieldsV1: 13 | f:metadata: 14 | f:annotations: 15 | .: {} 16 | f:kubectl.kubernetes.io/last-applied-configuration: {} 17 | f:spec: 18 | .: {} 19 | f:steps: {} 20 | manager: oc 21 | operation: Update 22 | time: "2021-03-03T08:04:56Z" 23 | name: echo-hello 24 | namespace: default 25 | resourceVersion: "1255505" 26 | selfLink: /apis/tekton.dev/v1beta1/namespaces/default/tasks/echo-hello 27 | uid: dcadb136-e20e-4dce-be20-0185b07e99cf 28 | spec: 29 | steps: 30 | - image: ubuntu 31 | name: echo 32 | resources: {} 33 | script: echo hello 34 | -------------------------------------------------------------------------------- /test/yaml-support/extract-task-pipeline.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | generateName: optional-workspace-when- 5 | spec: 6 | workspaces: 7 | - name: message-of-the-day 8 | optional: true 9 | description: | 10 | If a workspace is provided here then every file at the root of the workspace 11 | will be printed. 12 | tasks: 13 | - name: print-motd 14 | when: 15 | - input: "$(workspaces.message-of-the-day.bound)" 16 | operator: in 17 | values: ["true"] 18 | workspaces: 19 | - name: message-of-the-day 20 | workspace: message-of-the-day 21 | taskSpec: 22 | workspaces: 23 | - name: message-of-the-day 24 | optional: true 25 | metadata: 26 | annotations: 27 | manifestival: new 28 | tekton.dev/pipelines.minVersion: 0.12.1 29 | tekton.dev/tags: cli 30 | labels: 31 | app.kubernetes.io/version: '0.1' 32 | operator.tekton.dev/provider-type: redhat 33 | steps: 34 | - image: alpine 35 | script: | 36 | #!/usr/bin/env ash 37 | for f in "$(workspaces.message-of-the-day.path)"/* ; do 38 | echo "Message from $f:" 39 | cat "$f" 40 | echo "" # add newline 41 | done 42 | - name: print-default-motd 43 | when: 44 | - input: "$(workspaces.message-of-the-day.bound)" 45 | operator: in 46 | values: ["false"] 47 | taskSpec: 48 | steps: 49 | - name: print-default 50 | image: alpine 51 | script: | 52 | echo "No message-of-the-day workspace was provided. This is the default MOTD instead!" 53 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": ".", 11 | /* Strict Type-Checking Option */ 12 | "strict": false, /* enable all strict type-checking options */ 13 | /* Additional Checks */ 14 | "noUnusedLocals": false, /* Report errors on unused locals. */ 15 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 16 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 17 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 18 | "experimentalDecorators": true, 19 | "resolveJsonModule": true, 20 | "skipLibCheck": true 21 | }, 22 | "exclude": [ 23 | "node_modules", 24 | ".vscode-test", 25 | "src/webview", 26 | "test-resources" 27 | ], 28 | "include": [ 29 | "src", 30 | "test", 31 | "build", 32 | "ui-test" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /ui-test/all.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | import * as taskTest from './suite/task-test'; 6 | import * as tektonViewTest from './suite/tekton-view-test'; 7 | import * as extensionActivityTest from './public-suite/extension-activity-test'; 8 | import * as commandPaletteTest from './public-suite/command-palette-test'; 9 | import * as extensionViewTest from './public-suite/extension-view-test'; 10 | 11 | describe('VSCode Tekton UI Tests Suite', () => { 12 | commandPaletteTest.commandPaletteTest() 13 | extensionActivityTest.extensionActivityTest(); 14 | extensionViewTest.extensionViewTest(); 15 | 16 | const clusterUrl = process.env.CLUSTER_URL || 'https://api.openshift4.cluster.adapters-crs-qe.com:6443'; 17 | const username = process.env.CLUSTER_USER || 'kubeadmin'; 18 | const password = process.env.CLUSTER_PASSWORD || 'password'; 19 | 20 | tektonViewTest.tektonViewTest(clusterUrl, username, password); 21 | taskTest.taskTest(clusterUrl, username, password); 22 | }); 23 | 24 | -------------------------------------------------------------------------------- /ui-test/common/constants.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | export namespace commands { 6 | //General commands 7 | export const VERSION = 'Tekton: Tekton Version'; 8 | export const REFRESH = 'Tekton: Refresh View'; 9 | export const SHOW_OUTPUT_CHANNEL = 'Tekton: Show Output Channel'; 10 | 11 | //Tasks related commands 12 | export const START_TASK = 'Tekton: Start Task'; 13 | export const LIST_TASK_RUN = 'Tekton: List TaskRuns from Task'; 14 | export const SHOW_TASK_RUN_LOGS = 'Tekton: Show Task Run Logs'; 15 | } 16 | 17 | export namespace views { 18 | export const TEKTON_TITLE = 'Tekton Pipelines'; 19 | export const TEKTON_CATS = [TEKTON_TITLE, 'Debug Sessions', 'TektonHub']; 20 | } 21 | -------------------------------------------------------------------------------- /ui-test/public-suite/all-public.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | import * as extensionActivityTest from './extension-activity-test'; 7 | import * as commandPaletteTest from './command-palette-test'; 8 | import * as extensionViewTest from './extension-view-test'; 9 | 10 | describe('VSCode Tekton Public UI Tests Suite', () => { 11 | commandPaletteTest.commandPaletteTest() 12 | extensionActivityTest.extensionActivityTest(); 13 | extensionViewTest.extensionViewTest(); 14 | }); 15 | -------------------------------------------------------------------------------- /ui-test/public-suite/command-palette-test.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | import { InputBox, Workbench, EditorView } from 'vscode-extension-tester'; 6 | import { expect } from 'chai'; 7 | 8 | export function commandPaletteTest() : void{ 9 | 10 | describe('Tekton Command Palette Test', () => { 11 | 12 | before(async function() { 13 | this.timeout(20000); 14 | await new EditorView().closeAllEditors(); 15 | }); 16 | 17 | it('Search Tekton', async function(){ 18 | this.timeout(20000); 19 | await new Workbench().openCommandPrompt(); 20 | const paletteInput = await InputBox.create(); 21 | await paletteInput.setText('> tekton'); 22 | 23 | const tektonPicks = await paletteInput.getQuickPicks(); 24 | expect(tektonPicks).not.empty; 25 | }); 26 | 27 | after(async function() { 28 | this.timeout(20000); 29 | await new EditorView().closeAllEditors(); 30 | }); 31 | }); 32 | } 33 | -------------------------------------------------------------------------------- /ui-test/public-suite/extension-activity-test.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | import { SideBarView, ActivityBar, EditorView } from 'vscode-extension-tester'; 6 | import { expect } from 'chai'; 7 | import { views } from '../common/constants'; 8 | 9 | export function extensionActivityTest() : void{ 10 | 11 | describe('Tekton Activity Test', () => { 12 | 13 | before(async function() { 14 | this.timeout(20000); 15 | await new EditorView().closeAllEditors(); 16 | }); 17 | 18 | it('Check Tekton Pipelines Exists', async function(){ 19 | this.timeout(20000); 20 | const tektonPip = await new ActivityBar().getViewControl(views.TEKTON_TITLE); 21 | expect(tektonPip).not.undefined; 22 | }); 23 | 24 | it('Check Tekton View Categories', async function(){ 25 | this.timeout(20000); 26 | await (await new ActivityBar().getViewControl(views.TEKTON_TITLE)).openView(); 27 | const tektonCats = await new SideBarView().getContent().getSections(); 28 | expect(tektonCats.length).equals(3); 29 | expect(await Promise.all(tektonCats.map(async item => await item.getTitle()))).to.has.members(views.TEKTON_CATS); 30 | }); 31 | 32 | it('Check Tekton Pipelines Actions', async function(){ 33 | this.timeout(20000); 34 | await (await new ActivityBar().getViewControl(views.TEKTON_TITLE)).openView(); 35 | const tektonPipSection = await new SideBarView().getContent().getSection(views.TEKTON_TITLE); 36 | await tektonPipSection.expand(); 37 | expect(tektonPipSection.isExpanded()); 38 | 39 | 40 | const actions = await tektonPipSection.getActions(); 41 | expect(actions.length).greaterThan(0); 42 | }); 43 | 44 | after(async function() { 45 | this.timeout(20000); 46 | await new EditorView().closeAllEditors(); 47 | }); 48 | }); 49 | } 50 | -------------------------------------------------------------------------------- /ui-test/public-suite/extension-view-test.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | import { ActivityBar, EditorView, ExtensionsViewItem } from 'vscode-extension-tester'; 6 | import { expect } from 'chai'; 7 | 8 | export function extensionViewTest() : void{ 9 | 10 | describe('Tekton Extension View Test', () => { 11 | 12 | before(async function() { 13 | this.timeout(20000); 14 | await new EditorView().closeAllEditors(); 15 | }); 16 | 17 | it('Check Tekton Installation And Information', async function(){ 18 | this.timeout(20000); 19 | const extensionView = await (await new ActivityBar().getViewControl('Extensions')).openView(); 20 | const installedSection = await extensionView.getContent().getSection('Installed'); 21 | const tektonItem = await installedSection.findItem('@installed Tekton Pipelines') as ExtensionsViewItem; 22 | expect(tektonItem).not.undefined; 23 | 24 | const tektonTitle = await tektonItem.getTitle(); 25 | const tektonInstalled = await tektonItem.isInstalled(); 26 | const tektonAuthor = await tektonItem.getAuthor(); 27 | expect(tektonTitle).equals('Tekton Pipelines'); 28 | expect(tektonInstalled).is.true; 29 | expect(tektonAuthor).equals('Red Hat'); 30 | }); 31 | 32 | after(async function() { 33 | this.timeout(20000); 34 | await new EditorView().closeAllEditors(); 35 | }); 36 | }); 37 | } 38 | -------------------------------------------------------------------------------- /ui-test/resources/simple-task.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: example-task 5 | namespace: default 6 | spec: 7 | params: 8 | - name: appName 9 | default: testApp 10 | type: string 11 | steps: 12 | - image: registry.redhat.io/ubi7/ubi-minimal 13 | command: 14 | - /bin/bash 15 | - '-c' 16 | - echo 17 | - $(inputs.params.appName) -------------------------------------------------------------------------------- /ui-test/suite/dummy-test.ts: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | import { expect } from 'chai'; 6 | 7 | export function dummyTest(): void { 8 | describe('Dummy public tests', () => { 9 | it('My Concrete dummy test', () => { 10 | expect(1).to.be.true; 11 | }) 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------------------------- 2 | * Copyright (c) Red Hat, Inc. All rights reserved. 3 | * Licensed under the MIT License. See LICENSE file in the project root for license information. 4 | *-----------------------------------------------------------------------------------------------*/ 5 | 6 | // eslint-disable-next-line @typescript-eslint/no-var-requires 7 | const path = require('path'); 8 | 9 | module.exports = { 10 | performance: { hints: false }, 11 | entry: { 12 | 'pipeline-preview': {import: './src/webview/pipeline-preview/index.ts', filename: 'webview/[name]/index.js'}, 13 | 'pipeline-wizard': {import: './src/webview/pipeline/app/index.ts', filename: 'webview/[name]/index.js'}, 14 | 'bundle': {import: './src/webview/bundle/index.tsx', filename: 'webview/[name]/index.js'}, 15 | 'tekton-hub': {import: './src/webview/hub/index.ts', filename: 'webview/[name]/index.js'}, 16 | 'resource-view': {import: './src/webview/resource-page/index.ts', filename: 'webview/[name]/index.js'} 17 | }, 18 | module: { 19 | rules: [ 20 | { 21 | test: /\.tsx?$/, 22 | use: 23 | { 24 | loader: 'ts-loader', 25 | options: { 26 | configFile: 'webview-tsconfig.json' 27 | } 28 | }, 29 | exclude: /node_modules/, 30 | }, 31 | { 32 | test: /\.(css|scss)$/, 33 | use: [ 34 | { 35 | loader: 'style-loader', 36 | }, 37 | { 38 | loader: 'css-loader', 39 | }, 40 | { 41 | loader: 'sass-loader', 42 | } 43 | ] 44 | }, 45 | { 46 | test: /\.(woff|woff2|ttf|eot)$/, 47 | loader: 'file-loader', 48 | options: { 49 | name: '[name].[ext]', 50 | outputPath: 'webview/assets/' 51 | } 52 | }, 53 | { 54 | test: /\.(jpe?g|png|svg?)(\?[a-z0-9=&.]+)?$/, 55 | use: 'base64-inline-loader?limit=1000&name=[name].[ext]' 56 | } 57 | ] 58 | }, 59 | resolve: { 60 | extensions: ['.tsx', '.ts', '.js'] 61 | }, 62 | devtool: 'inline-source-map', 63 | output: { 64 | filename: '[name].js', 65 | path: path.resolve(__dirname, 'out') 66 | } 67 | }; 68 | -------------------------------------------------------------------------------- /webview-tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist/", 5 | "jsx": "react", 6 | "lib": [ 7 | "es2018", 8 | "DOM", 9 | "DOM.Iterable" 10 | ] 11 | }, 12 | "include": [ 13 | "./src" 14 | ], 15 | "exclude": [ 16 | "./src/util" 17 | ] 18 | } 19 | --------------------------------------------------------------------------------