Jenkins with pylint gives build failure

守給你的承諾、 提交于 2019-12-05 02:37:14

it seems that your pylint execution exit with a non-zero status (missing script, bad options...), maybe you exit the script with an exception raised or a sys.exit(something_else_than_zero)

You can also simply put a

pylint || exit 0

in the shell cmdline. The Pylint plugin will fail the build anyway by checking the result of pyllint.

Pylint has the unpleasant behavior to return a non-zero exit code even only if a small warning issue was found. Only when everything was fine, 0 is returned (see man page).

As usually a non-zero code denotes an error, Jenkins fails the build.

I see two ways to overcome this:

  • Use a small script around pylint that always returns 0. Then jenkins will not fail because of pylint. I use a small python script calling pylint with os.system() and sys.exit(0) after than. You can see it as overriding the error code of pylint.
  • Patch pylint. For example, on my Linux system the sys.exit() call is in the file /usr/lib/pymodules/python2.6/pylint/lint.py
kmmbvnr

Recent rylint have option for not calling sys exit

lint.Run(args, exit=False, **kwargs)
sheryl pinto

In Pylint 1.9.3, there is a --exit-zero flag.

https://github.com/PyCQA/pylint/blob/1.9/ChangeLog#L47

I agree with @dmeister, but with pipeline code (Jenkinsfile) I suggest a try/catch and then parsing the error. This way you can determine if you're just getting status bits from pylint (see the Pylint docs), whether pylint reports a usage error, or whether there was a catastrophic fail:

try {       
    sh 'pylint --output-format=parseable my_module'
} catch ( pylint_rc ) {
    // pylint_rc will be of the form
    // "hudson.AbortException: script returned exit code NN"
    // where NN is 1-63 and represents bit field;
    // bits 0-4 indicate lint-ish issues in analyzed code,
    // bit 5 indicates pylint usage error
    echo "pylint_rc= \'$pylint_rc\'"
    String rc = "$pylint_rc"
    String code = rc.split()[5]
    echo "Isolated return code string value $code"
    int value = code.toInteger()

    // catastrophic/crash error returns a 1; else there is a pylint return code
    int error_bits_code = value & 0x20
    int lint_bits_code = value & 0x1f
    echo "pylint error_bits_code=$error_bits_code ; lint_bits_code=$lint_bits_code"
    if ( (value == 1) || (error_bits_code != 0) ) {
        currentBuild.result = "FAILURE"
        throw pylint_rc
    }
}

Apologies to groovy purists - groovy isn't my thing, so I'm sure this can be improved on - let me know. There is one known hole: if pylint detects only "fatal"-type errors (bit 0) and no other issues of any kind (bits 1-4 are not set) then this code will incorrectly throw an exception. But my code flags tons of issues, so that's not a problem for me. The fix (?parse error msg?) might be trivial for someone with groovy chops.

Ran into this today (although not using Jenkins).

In my case it was because of how Pylint encodes fatal-error-warning-refactor-convention-usage info in its exit code: https://docs.pylint.org/en/1.6.0/run.html#exit-codes

My fix:

#!/usr/bin/env sh

# Wraps Pylint invocation to produce shell-friendly exit codes
# Because Pylint exit codes are weird:
# https://docs.pylint.org/en/1.6.0/run.html#exit-codes

PYTHON_EXECUTABLE=python
if [ ! -z $PYTHON_ENV ]; then
    PYTHON_EXECUTABLE="$PYTHON_ENV/bin/python"
fi

${PYTHON_EXECUTABLE} -m pylint $@

PYLINT_EXIT_CODE=$?

exit $(($PYLINT_EXIT_CODE % 4))

(Gist: https://gist.github.com/nkashy1/ae59d06d4bf81fb72047fcd390d08903)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!