ibm / tekton-lint Goto Github PK
View Code? Open in Web Editor NEWLinter for Tekton definitions.
License: Apache License 2.0
Linter for Tekton definitions.
License: Apache License 2.0
tekton-lint
should have a rule which checks how a Task
is used. Either with:
script
command
& args
Developers should follow a convention and use only one of these consistently. We should add a rule which checks this and warns the developers if they are mixed.
With the same behavior as in ESLint.
For example a task with workspaces defined as
- name: secrets
description: |
What directory contains the secrets required for this task?
optional: true
readOnly: true
mountPath: /run/pipeline/secrets
when used would report an error if the optional workspace wasn't specified.
Updated to only report mandatory workspaces
Tekton CD TEP 003 suggests a deprecation label be used on Resources that are to be marked as deprecated in a catalog.
Linter should watch for the label tekton.dev/deprecated: true
and show a warning (or error if the user override the rule severity with their custom config).
Example for non-deprecated resource
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: some-task
labels:
app.kubernetes.io/version: "1.0.3"
spec:
Example for a deprecated resource
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: some-task
labels:
app.kubernetes.io/version: "1.0.3"
tekton.dev/deprecated: true
spec:
Given this example... it will fail as the workspace defined in the task just uses the name
field - code is assuming that the workspace
field is present instead
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: run-checks
spec:
params:
workspaces:
- name: workspace-checks
tasks:
- name: run-checks
taskRef:
name: task-run-checks
workspaces:
- name: workspace-checks
Documentation here indicates that workspace
is optional
https://tekton.dev/docs/pipelines/pipeline-api/#tekton.dev/v1.WorkspacePipelineTaskBinding
Adjusting the code so that if workspace is specified it must match up with the one defined in the pipeline, if it's not present the name must match up instead.
This project would be useful to any Tekton Task author. Have you considered donating this project to the tektoncd community?
tekton-lint/regression-tests/no-extra-param.yaml
Lines 51 to 56 in 7218c6b
It should be reported by the no-extra-param
rule.
tekton-lint/regression-tests/no-extra-param.yaml
Lines 63 to 65 in 7218c6b
It should be reported by the no-extra-param
rule.
tekton-lint/regression-tests/no-duplicate-env.yaml
Lines 46 to 49 in da5f5d1
It should be reported by the no-duplicate-env
rule.
Describe the bug
I received a 500 from the backend with this syntax:
spec:
triggers:
- bindings:
name: github-pr-binding
template:
name: pr-template
with pipelineId: c2cd6a8d-ea5a-47b0-913e-cd172d63833f, transactionId: d0a52994-03da-4841-9a45-8e6d375fbb19, error: (trigger.bindings || (trigger.binding && [trigger.binding]) || []).forEach is not a function at TypeError: (trigger.bindings || (trigger.binding && [trigger.binding]) || []).forEach is not a function
at Object.getTemplatedResources (/home/node/lib/pipelineutil.js:708:76)
To Reproduce
spec:
triggers:
- bindings:
name: github-pr-binding
template:
name: pr-template
Expected behavior
I expected a linting error.
I expected a proper error handling in the backend.
The fix
spec:
triggers:
- bindings:
- name: github-pr-binding
template:
name: pr-template
Thank you :)
tekton-lint/regression-tests/no-duplicate-param.yaml
Lines 66 to 67 in 6cc83be
It should be reported by the no-duplicate-param
rule.
I recently started using pre-commit to manage the installation and running of linters in one of my projects. Basically (read their docs for more info) developers on projects can save references to linters/checkers/etc in a .pre-commit-config.yaml
file in their repository, and new developers can get them installed more quickly and consistently - plus they can be configured to run on every git commit.
Some of the linters "supported" by pre-commit are in mirrors of the main projects (for example: prettier), but other projects have added the required hook definitions to their repositories directly (for example: go-jsonnet). I think it would be great if we supported using tekton-lint through pre-commit.
To "support" using pre-commit with this project, we would just need to add a .pre-commit-hooks.yaml
file, with some specific information. I've made a simple fork to test this out, and it looks good - although more tests might be needed: https://github.com/JustinKuli/tekton-lint/blob/main/.pre-commit-hooks.yaml. I'd be happy to open a PR based on that if there is interest.
To be clear, I'm not proposing that this project should start using/enforcing use of pre-commit in its own development workflow. This issue is focused on making tekton-lint easier for other projects to use via pre-commit.
tekton-lint/regression-tests/no-duplicate-env.yaml
Lines 63 to 72 in da5f5d1
It should be reported by the no-duplicate-env
rule.
First off, congratulations on your open source release! That's momentous!
Now, on to the error. Linting my pipeline results in the following:
TypeError: Cannot read property 'spec' of undefined
at /mnt/c/Users/JAMESTANNER/Development/microservices-build-agent/node_modules/tekton-lint/rules/no-undefined-result.js:14:83
I think that this happens because I've got an external task which is loaded separately from the catalog. So it's not included in the files being linted. So there's a taskref in the pipeline, but no task to match against.
I'd expect the behavior here to be a warning, or perhaps a displayed error, about the missing task. But I'd expect the linter to complete rather than throwing an internal error.
If you have access to the IBM internal github, the pipeline in question is here: https://github.ibm.com/TAAS/microservices-builds/blob/main/tekton-pipeline/pipeline-push.yaml
From some extra logging I injected into the code, it looks like it fails on the fetch-from-git
task.
As you can see below we have a ClusterTask being used at our pipelines and tekton-lint shows it's reference as missing, but it is defined
/workdir # tekton-lint tasks/* pipelines/pipeline.yml --quiet
pipelines/pipeline-confluence-docs-default.yml:
error (38,15,38,28): Pipeline 'docs-default' references task 'webhook-debug' but the referenced task cannot be found. To fix this, include all the task definitions to the lint task for this pipeline.
/workdir # head -n5 tasks/cluster-task-webhook-debug.yml
---
apiVersion: tekton.dev/v1beta1
kind: ClusterTask
metadata:
name: webhook-debug
/workdir # grep 'webhook-debug' -C1 pipelines/pipeline-docs.yml
taskRef:
name: webhook-debug
kind: ClusterTask
Is your feature request related to a problem? Please describe.
make a github action for this tool.
Describe the solution you'd like
make a github action support for this tool so that we can easily integrate this tool with open source project.
Describe alternatives you've considered
Additional context
tekton-lint (5.0) is complaining on the following file: https://github.com/open-toolchain/tekton-catalog/blob/master/git/sample-skip-ci/listener-skip-ci.yaml
git/sample-skip-ci/listener-skip-ci.yaml:
error (54,9,54,22): 'github-commit' is already defined (as a 'TriggerBinding')
error (69,9,69,22): 'github-commit' is already defined (as a 'EventListener')
...
AFAIK nothing prevent to use same name for different K8S resources/Tekton resources as long as they are of different types
tekton-lint/regression-tests/no-duplicate-param.yaml
Lines 85 to 88 in 3eb30c3
It should be reported by the no-duplicate-param
rule.
Handle the tt.params
syntax for names
see https://tekton.dev/docs/triggers/triggertemplates/#specifying-parameters
Hey All!
Im trying to add the Tekton-lint
to the GitHub Super-Linter and have 1 ask for improvement.
Currently, if you run the following code:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: example-task-name
spec:
params:
- name: pathToDockerFile
type: string
description: The path to the dockerfile to build
default: /workspace/workspace/Dockerfile
resources:
inputs:
- name: workspace
type: git
outputs:
- name: builtImage
type: image
steps:
- name: ubuntu-example
image: ubuntu
args: ["ubuntu-build-example", "SECRETS-example.md"]
- image: gcr.io/example-builders/build-example
command: ["echo"]
args: ["$(params.pathToDockerFile)"]
- name: dockerfile-pushexample
image: gcr.io/example-builders/push-example
args: ["push", "$(resources.outputs.builtImage.url)"]
volumeMounts:
- name: example-volume
mountPath: /var/run/docker.sock
volumes:
- name: example-volume
emptyDir: {}
It will complete successfully with error code 0
But if i remove the line:
kind: Task
It will run and show no output, and exit with exit code 0
... Can this be set to exit with error code if it fails to read the data?
thanks!
With the same behavior as in ESLint
In 0.5.2 we should report missing parameters in taskSpec tasks
Example:
- name: inline-task
params:
- name: pipeline-debug
value: $(params.pipeline-debug)
workspaces:
- name: secrets
workspace: artifacts
taskSpec:
workspaces:
- name: secrets
mountPath: /secrets
params:
- name: pipeline-debug
stepTemplate:
env:
- name: PIPELINE_RUN_ID
valueFrom:
fieldRef:
fieldPath: metadata.annotations['devops.cloud.ibm.com/tekton-pipeline']
steps:
- name: setup
image: node:alpine
script: |
#!/bin/bash
set -e -o pipefail
if [ $PIPELINE_DEBUG == 1 ]; then
pwd
env
trap env EXIT
set -x
fi
export TOKEN=$(cat "/secrets/$(params.token)")
The line
export TOKEN=$(cat "/secrets/$(params.token)")
use a parameter token
which was not added nor provided for the task, the linter is missing this.
The tekton-lint npm package seems to have an "Apache-2.0" license in NPM, since it is specified in the package.json.
However, it would make it even more clearer to have a LICENSE file in the repository, so the GitHub interface could show the license and could also be returned by the GitHub API.
It is trivial to add a license on GitHub. The easiest way is through the web interface: Go to "Add file" then "Create new file", enter LICENSE
as the file name, then a new button appears with "Choose a license template". Select the Apache 2.0, and finish up and commit. I added my own screenshots below, but some help is also available in the GitHub docs here:
https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/adding-a-license-to-a-repository
I could make a pull request too, but I think it's more appropriate to have it committed by the owners or maintainers.
Thanks!
tekton-lint/regression-tests/no-duplicate-param.yaml
Lines 72 to 73 in 6cc83be
It should be reported by the no-duplicate-param
rule.
tekton-lint/regression-tests/prefer-when-expression.yaml
Lines 33 to 34 in 62ff0eb
This should be reported by prefer-when-expression
We have a bunch of pipelines with the finally section.
The problem is that we see warning like the following:
warning (15,7,17,1): Pipeline 'pipeline-xx-yy-zzz' defines parameter 'example', but it's not used anywhere in the spec
and in the pipeline we have:
finally:
- name: yyyyyyy
taskRef:
name: task-yyyyyy
params:
- name: example
value: $(params.example)
workspaces:
- name: task-pvc
workspace: pipeline-pvc
Is any way to fix this?
Conditions
are deprecated in favor of WhenExpressions
See https://github.com/tektoncd/pipeline/blob/v0.16.3/docs/pipelines.md#guard-task-execution-using-conditions
When running on the latest release:
Cannot read properties of undefined (reading 'key'
Hi there,
Just tried out your new lint tool (congrats!) and I got many errors like the following:
error (4,9,4,20): 'ci-template' is already defined (as a 'TriggerTemplate')
The reason is that I've multiple folders containing tekton definitions and sometimes they have the same name used in another folder. This is fine for my use as my toolchains only pulls in one of these folders. Can we have a switch that only checks for dupe names within the same folder... maybe there already is?
tekton-lint/regression-tests/no-extra-param.yaml
Lines 57 to 62 in 7218c6b
It should be reported by the no-extra-param
rule.
Names (ie. metadata.name
) must be DNS subdomain names.
tekton-lint/regression-tests/no-invalid-name.yaml
Lines 9 to 14 in 8de87d9
tekton-lint/regression-tests/no-invalid-name.yaml
Lines 16 to 21 in 8de87d9
tekton-lint/regression-tests/no-invalid-name.yaml
Lines 23 to 28 in 8de87d9
tekton-lint/regression-tests/no-invalid-name.yaml
Lines 30 to 35 in 8de87d9
tekton-lint/regression-tests/no-invalid-name.yaml
Lines 78 to 84 in 8de87d9
These should be reported by no-invalid-name
Each rule should have its own test file:
no-deprecated-resource
#55no-duplicate-env
#32no-duplicate-param
#35no-duplicate-resource
no-extra-param
#41no-invalid-name
#56no-invalid-param-type
no-latest-image
no-missing-param
no-missing-resource
no-missing-workspace
no-pipeline-missing-task
no-pipeline-task-cycle
no-resourceversion
no-undefined-param
no-undefined-result
no-undefined-volume
no-unused-param
prefer-beta
prefer-kebab-case
prefer-when-expression
#52Is your feature request related to a problem? Please describe.
At the moment the tool supports only some pre-defined rules defined here https://github.com/IBM/tekton-lint/blob/main/src/rule-loader.ts
It would be great if users could provide (and leave them to maintain) their custom rule implementations and specify how to treat the findings (e.g. error, warning, etc..).
An example would be like the following:
const forbidPipelinesWithoutRequiredAnnotation = (docs, tekton, report) => {
for (const pipeline of Object.values(tekton.pipelines)) {
const pipelineAnnotations = Object.keys(pipeline.metadata.annotations);
if (!pipelineAnnotations.includes('my/required-annotation')) {
report(
`Pipeline '${pipeline.metadata.name}' does not specify the 'my/required-annotation' annotation`,
);
}
}
};
module.exports = {
rules: {
'no-required-annotations': 'error'
},
customRules: {
'no-required-annotations': forbidPipelinesWithoutRequiredAnnotation
}
}
Describe the solution you'd like
Support (on top of the yaml configuration) a JS (or TS) configuration file as well, e.g. .tektonlintrc.js
where it is possible to define a set of custom rules or provide a specific rule
as a function (instead of providing a string 'error' or 'warning', and leave the implementation to handle it).
Describe alternatives you've considered
At the moment there is no way to provide custom rules since they are specified in the mentioned file above
Additional context
Add JS File loader in the ./src/config.ts
main constructor. An example below:
if (fs.lstatSync(user_tektonlintrc).isDirectory()) {
user_tektonlintrc = path.join(user_tektonlintrc, '.tektonlintrc.yaml');
}
if (fs.lstatSync(user_tektonlintjs).isDirectory()) {
user_tektonlintjs = path.join(user_tektonlintjs, '.tektonlintrc.js');
}
let customRcConfig = {
...defaultConfig
};
if (fs.existsSync(user_tektonlintrc)) {
const customRcFile = fs.readFileSync(user_tektonlintrc, 'utf8');
customRcConfig = yaml.parse(customRcFile);
logger.info('Using .tektonlintrc.yaml at %s', user_tektonlintrc);
logger.info('customConfig %o', customRcConfig);
} else if (fs.existsSync(user_tektonlintjs)) {
customRcConfig = require(user_tektonlintjs);
logger.info('Using .tektonlintrc.js at %s', user_tektonlintrc);
logger.info('customConfig %o', customRcConfig);
} else {
logger.warn('Unable to find configuration - using defaults');
}
this._rulesConfig = { ...customRcConfig };
this._rulesConfig.rules = { ...customRcConfig.rules };
this._rulesConfig.customRules = { ...customRcConfig.customRules };
this._globs = [...cliConfig['_'], ...(customRcConfig.globs ? customRcConfig.globs : ['_'])];
tekton-lint/regression-tests/no-duplicate-param.yaml
Lines 25 to 26 in 6cc83be
It should be reported by the no-duplicate-param
rule.
It's a common pattern to bundle a Pipeline
+ TriggerBinding
+ TriggerTemplate
+ EventListener
into a subfolder, where these resources have the same name, but they live in different namespaces.
.
├── foo/
│ ├── listener.yaml
│ ├── trigger.yaml
│ ├── binding.yaml
│ └── pipeline.yaml
├── bar/
│ ├── listener.yaml
│ ├── trigger.yaml
│ ├── binding.yaml
│ └── pipeline.yaml
└── tasks/
├── task-1.yaml
└── task-2.yaml
The linter should be able to handle these definitions.
original issue: #4
tekton-lint/regression-tests/no-extra-param.yaml
Lines 21 to 26 in 7218c6b
step-1
is not a task name (it's the name of the TaskRun
). Actually, there's no standalone task, it's using an embedded task using taskSpec
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.