diff --git a/jobs/templates/includes/create-phabricator-artifacts.groovy.j2 b/jobs/templates/includes/create-phabricator-artifacts.groovy.j2 new file mode 100644 index 0000000..1a0d52e --- /dev/null +++ b/jobs/templates/includes/create-phabricator-artifacts.groovy.j2 @@ -0,0 +1,29 @@ +withCredentials([ + string(credentialsId: 'swh-public-ci', + variable: 'PHAB_CONDUIT_TOKEN')]) { + sh ''' + if [ -n "$PHID" ]; then + echo "{ + \\\"buildTargetPHID\\\": \\\"$PHID\\\", + \\\"artifactKey\\\": \\\"jenkins.uri\\\", + \\\"artifactType\\\": \\\"uri\\\", + \\\"artifactData\\\": { + \\\"uri\\\": \\\"${BUILD_URL}\\\", + \\\"name\\\": \\\"Jenkins\\\", + \\\"ui.external\\\": true + } + }" | arc call-conduit --conduit-uri $PHAB_CONDUIT_URL --conduit-token $PHAB_CONDUIT_TOKEN harbormaster.createartifact + echo "{ + \\\"buildTargetPHID\\\": \\\"$PHID\\\", + \\\"artifactKey\\\": \\\"jenkins.console.uri\\\", + \\\"artifactType\\\": \\\"uri\\\", + \\\"artifactData\\\": { + \\\"uri\\\": \\\"${BUILD_URL}console\\\", + \\\"name\\\": \\\"Jenkins console\\\", + \\\"ui.external\\\": true + } + }" | arc call-conduit --conduit-uri $PHAB_CONDUIT_URL --conduit-token $PHAB_CONDUIT_TOKEN harbormaster.createartifact + python3 -m pyarcanist send-message work $PHID + fi + ''' +} diff --git a/jobs/templates/swh-pipeline.groovy.j2 b/jobs/templates/swh-pipeline.groovy.j2 index e659315..e6b8123 100644 --- a/jobs/templates/swh-pipeline.groovy.j2 +++ b/jobs/templates/swh-pipeline.groovy.j2 @@ -1,225 +1,199 @@ pipeline { agent { docker { image 'swh-jenkins/{{docker_image}}' args '--tmpfs /tmp:exec --mount type=volume,src=shared-jenkins-cachedir,dst=/home/jenkins/.cache' } } environment { PHAB_CONDUIT_URL = 'https://forge.softwareheritage.org/api/' } stages { stage('Checkout') { steps { - withCredentials([ - string(credentialsId: 'swh-public-ci', - variable: 'PHAB_CONDUIT_TOKEN')]) { - sh ''' - if [ -n "$PHID" ]; then - echo "{ - \\\"buildTargetPHID\\\": \\\"$PHID\\\", - \\\"artifactKey\\\": \\\"jenkins.uri\\\", - \\\"artifactType\\\": \\\"uri\\\", - \\\"artifactData\\\": { - \\\"uri\\\": \\\"${BUILD_URL}\\\", - \\\"name\\\": \\\"Jenkins\\\", - \\\"ui.external\\\": true - } - }" | arc call-conduit --conduit-uri $PHAB_CONDUIT_URL --conduit-token $PHAB_CONDUIT_TOKEN harbormaster.createartifact - echo "{ - \\\"buildTargetPHID\\\": \\\"$PHID\\\", - \\\"artifactKey\\\": \\\"jenkins.console.uri\\\", - \\\"artifactType\\\": \\\"uri\\\", - \\\"artifactData\\\": { - \\\"uri\\\": \\\"${BUILD_URL}console\\\", - \\\"name\\\": \\\"Jenkins console\\\", - \\\"ui.external\\\": true - } - }" | arc call-conduit --conduit-uri $PHAB_CONDUIT_URL --conduit-token $PHAB_CONDUIT_TOKEN harbormaster.createartifact - python3 -m pyarcanist send-message work $PHID - fi - ''' - } + {% filter indent(width=8) %} + {%- include 'includes/create-phabricator-artifacts.groovy.j2' -%} + {% endfilter %} checkout([ $class: 'GitSCM', branches: [[name: "${params.REVISION}"]], doGenerateSubmoduleConfigurations: false, extensions: [], gitTool: 'Default', submoduleCfg: [], userRemoteConfigs: [ [url: 'https://forge.softwareheritage.org/source/{{repo_name}}.git'], ], browser: [$class: 'Phabricator', repoUrl: 'https://forge.softwareheritage.org', repo: '{{name}}'] ]) } } {%- if phabricator_diff %} stage('Apply phabricator diff') { steps { script { comment = sh( script: ''' #!/bin/bash set -e ORIGINAL_TAG=base-revision-${BUILD_NUMBER}-D${REV_ID} ORIGINAL_COMMIT=$(git rev-parse --short=10 HEAD) echo "==== Patch application report for D${REV_ID} (id=${DIFF_ID}) ====" echo git tag -f ${ORIGINAL_TAG} >/dev/null git fetch -n ${STAGING_URI} +refs/tags/phabricator/diff/${DIFF_ID}:diff-target +refs/tags/phabricator/base/${DIFF_ID}:diff-base >/dev/null rebased=0 if git merge-base --is-ancestor diff-base HEAD; then echo "**Rebasing** onto ${ORIGINAL_COMMIT}..." echo echo '```' git rebase --onto ${ORIGINAL_TAG} diff-base diff-target && rebased=1 || rebase_exit=$? echo '```' if [ $rebased -eq 0 ]; then echo echo "Rebase failed (ret=${rebase_exit})!" echo echo '```' git rebase --abort || true echo '```' fi fi merged=0 if [ $rebased -eq 0 ]; then echo "Could not rebase; Attempt **merge** onto ${ORIGINAL_COMMIT}..." echo echo '```' git merge --no-edit diff-target && merged=1 || merge_exit=$? echo '```' if [ $merged -eq 0 ]; then echo echo "Merge failed (ret=${merge_exit})!" echo fi fi if [ $merged -eq 1 -o $rebased -eq 1 ]; then echo echo "===== Changes applied before test =====" echo echo '```' git log ${ORIGINAL_TAG}.. echo '```' else echo '**Attempts to apply the diff failed!**' exit 1 fi ''', label: 'Apply patch', returnStdout: true, ) writeFile( file: '.phabricator-comment', text: comment, ) } } } {%- endif %} stage('Cleanup') { steps { {% filter indent(width=8) %} {%- include 'includes/cleanup-workspace.groovy.j2' -%} {% endfilter %} } } stage('Static analysis') { steps { echo 'flake8' sh '''python3 -m tox -e flake8''' echo 'mypy' sh '''if python3 -m tox -a 2>/dev/null | grep -qx mypy ; then python3 -m tox -e mypy ; fi''' echo 'radon'; sh ''' mkdir -p reports python3 -m radon raw --json swh/ > reports/raw_report.json python3 -m radon cc --json swh/ > reports/cc_report.json python3 -m radon mi --json swh/ > reports/mi_report.json python3 -m radon hal --json swh/ > reports/hal_report.json python3 -m radon cc --xml swh/ > reports/cc_report.xml ''' } } // static analysis stage('Unit tests') { options { timeout(time: 20, unit: 'MINUTES') } steps { sh ''' python3 -m tox -e $TOX_ENVIRONMENT -- \ --cov-report=xml \ --junit-xml=test-results.xml \ -v ''' } post { always { step([$class: 'CoberturaPublisher', autoUpdateHealth: false, autoUpdateStability: false, coberturaReportFile: 'coverage.xml', failNoReports: false, failUnhealthy: false, failUnstable: false, maxNumberOfBuilds: 10, onlyStable: false, sourceEncoding: 'ASCII', zoomCoverageChart: false]) // JUnit report junit( allowEmptyResults: true, testResults: 'test-results.xml', ) // Warnings NG recordIssues( enabledForFailure: true, tools: [ ccm(pattern: '**/reports/cc_report.xml'), ], ) } } // post } // unit tests } // stages post { always { // Archive a few report files archiveArtifacts allowEmptyArchive: true, artifacts: 'reports/*,*.xml,tox*.ini', fingerprint: true step([$class: 'PhabricatorNotifier', commentOnSuccess: true, commentWithConsoleLinkOnFailure: true, commentFile: '.phabricator-comment', commentSize: '1000000', preserveFormatting: true, processLint: true, lintFile: '.phabricator-lint', lintFileSize: '1000000', ]) {% filter indent(width=6) %} {%- include 'includes/cleanup-workspace.groovy.j2' -%} {% endfilter %} } // always } // post } // pipeline