@Library('salt@1.1') _ // Define the maximum time, in hours, that a test run should run for def global_timeout = 3 def salt_target_branch = 'master' properties([ buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '10')), ]) def shell_header // Be sure to cancel any previously running builds def buildNumber = env.BUILD_NUMBER as int if (buildNumber > 1) { // This will cancel the previous build which also defined a matching milestone milestone(buildNumber - 1) } // Define a milestone for this build so that, if another build starts, this one will be aborted milestone(buildNumber) def lint_report_issues = [] wrappedNode('lint', global_timeout, '#jenkins-prod-pr') { try { shell_header = '' withEnv(["SALT_TARGET_BRANCH=${salt_target_branch}"]) { // Checkout the repo stage('checkout-scm') { cleanWs notFailBuild: true checkout scm } // Setup the kitchen required bundle stage('Setup') { sh shell_header + ''' # Need -M to detect renames otherwise they are reported as Delete and Add, need -C to detect copies, -C includes -M # -M is on by default in git 2.9+ git diff --name-status -l99999 -C "origin/${SALT_TARGET_BRANCH}" > file-list-status.log # the -l increase the search limit, lets use awk so we do not need to repeat the search above. gawk 'BEGIN {FS="\\t"} {if ($1 != "D") {print $NF}}' file-list-status.log > file-list-changed.log gawk 'BEGIN {FS="\\t"} {if ($1 == "D") {print $NF}}' file-list-status.log > file-list-deleted.log (git diff --name-status -l99999 -C "origin/${SALT_TARGET_BRANCH}" "origin/$BRANCH_NAME";echo "---";git diff --name-status -l99999 -C "origin/$BRANCH_NAME";printenv|grep -E '=[0-9a-z]{40,}+$|COMMIT=|BRANCH') > file-list-experiment.log eval "$(pyenv init -)" pyenv --version pyenv install --skip-existing 2.7.15 pyenv install --skip-existing 3.6.8 pyenv shell 3.6.8 2.7.15 python --version pip3 install -U nox-py2 nox --version # Create the required virtualenvs in serial nox --install-only -e lint-salt nox --install-only -e lint-tests ''' } archiveArtifacts( artifacts: 'file-list-status.log,file-list-changed.log,file-list-deleted.log,file-list-experiment.log', allowEmptyArchive: true ) } stage('Lint Changes') { try { parallel( lintSalt: { stage('Lint Salt Changes') { if (readFile('file-list-changed.log') =~ /(?i)(^|\n)(salt\/.*\.py|setup\.py)\n/) { sh shell_header + ''' eval "$(pyenv init - --no-rehash)" pyenv shell 3.6.8 2.7.15 EC=254 export PYLINT_REPORT=pylint-report-salt-chg.log grep -Ei '^salt/.*\\.py$|^setup\\.py$' file-list-changed.log | xargs -r '--delimiter=\\n' nox -e lint-salt -- EC=$? exit $EC ''' } else { // Always lint something so reporting doesn't fail sh shell_header + ''' eval "$(pyenv init - --no-rehash)" pyenv shell 3.6.8 2.7.15 EC=254 export PYLINT_REPORT=pylint-report-salt-chg.log nox -e lint-salt -- salt/ext/__init__.py EC=$? exit $EC ''' } } }, lintTests: { stage('Lint Test Changes') { if (readFile('file-list-changed.log') =~ /(?i)(^|\n)tests\/.*\.py\n/) { sh shell_header + ''' eval "$(pyenv init - --no-rehash)" pyenv shell 3.6.8 2.7.15 EC=254 export PYLINT_REPORT=pylint-report-tests-chg.log grep -Ei '^tests/.*\\.py$' file-list-changed.log | xargs -r '--delimiter=\\n' nox -e lint-tests -- EC=$? exit $EC ''' } } } ) } finally { def changed_logs_pattern = 'pylint-report-*-chg.log' archiveArtifacts( artifacts: changed_logs_pattern, allowEmptyArchive: true ) lint_report_issues.add( scanForIssues( tool: pyLint(pattern: changed_logs_pattern, reportEncoding: 'UTF-8') ) ) } } stage('Lint Full') { if (env.CHANGE_BRANCH =~ /(?i)^merge[._-]/) { // perform a full linit if this is a merge forward and the change only lint passed. try { parallel( lintSaltFull: { stage('Lint Salt Full') { sh shell_header + ''' eval "$(pyenv init - --no-rehash)" pyenv shell 3.6.8 2.7.15 EC=254 export PYLINT_REPORT=pylint-report-salt-full.log nox -e lint-salt EC=$? exit $EC ''' } }, lintTestsFull: { stage('Lint Tests Full') { sh shell_header + ''' eval "$(pyenv init - --no-rehash)" pyenv shell 3.6.8 2.7.15 EC=254 export PYLINT_REPORT=pylint-report-tests-full.log nox -e lint-salt EC=$? exit $EC ''' } } ) } finally { def full_logs_pattern = 'pylint-report-*-full.log' archiveArtifacts( artifacts: full_logs_pattern, allowEmptyArchive: true ) lint_report_issues.add( scanForIssues( tool: pyLint(pattern: full_logs_pattern, reportEncoding: 'UTF-8') ) ) } } } } finally { publishIssues( enabledForFailure: true, aggregatingResults: true, referenceJobName: "${salt_target_branch}/salt-${salt_target_branch}-lint", qualityGates: [ [threshold: 1, type: 'TOTAL', unstable: false] ], issues: lint_report_issues ) } } // vim: ft=groovy