saltstack/salt

View on GitHub
.ci/lint

Summary

Maintainability
Test Coverage
@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 = 'develop'

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
                sh 'git fetch --no-tags https://github.com/saltstack/salt.git +refs/heads/${SALT_TARGET_BRANCH}:refs/remotes/origin/${SALT_TARGET_BRANCH}'
            }

            // 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 3.6.8
                pyenv shell 3.6.8
                python --version
                pip 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
                                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
                                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
                                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
                                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
                                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