Section | Description |
parameters | Accepts user input before build: branch, environment, flags. |
environment | Defines environment variables, including credential bindings. |
options | Controls build retention, timeout, log formatting. |
triggers | Automatically starts pipeline on SCM change or schedule. |
stages > parallel | Runs stages in parallel (e.g., lint & coverage). |
when | Conditional execution of stages (e.g., test only if RUN_TESTS == true). |
stash/unstash | Transfers files between stages/nodes. |
input | Manual approval before deploy (great for production safety). |
docker.withRegistry | Builds and pushes Docker image using Docker Hub credentials. |
post | Sends email notifications and performs cleanup actions. |
pipeline {
agent any
environment {
PYTHON_ENV = 'venv'
ARTIFACTORY_URL = 'https://your.jfrog.instance/artifactory'
ARTIFACTORY_REPO = 'python-release-local'
CHECKMARX_SERVER = 'your-checkmarx-server-url'
}
stages {
stage('Checkout from Bitbucket') {
steps {
git credentialsId: 'bitbucket-creds-id', url: 'https://bitbucket.org/org/project.git', branch: 'main'
}
}
stage('Setup Python Environment') {
steps {
sh '''
python3 -m venv ${PYTHON_ENV}
. ${PYTHON_ENV}/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-cov
'''
}
}
stage('Static Code Analysis - Checkmarx') {
steps {
script {
def scanStatus = sh(
script: '''
cx scan --project-name "MyPythonApp" --src . --sast-host ${CHECKMARX_SERVER} --report-format json --report-output checkmarx-result.json
''',
returnStatus: true
)
if (scanStatus != 0) {
error "❌ Checkmarx scan failed."
}
def highIssues = sh(script: "grep -c 'High' checkmarx-result.json || true", returnStdout: true).trim()
if (highIssues.toInteger() > 0) {
error "❌ High severity vulnerabilities found in Checkmarx. Failing pipeline."
}
}
}
}
stage('Run Unit Tests and Coverage Check') {
steps {
script {
def testStatus = sh(
script: '''
. ${PYTHON_ENV}/bin/activate
pytest --junitxml=test-results.xml --cov=. --cov-report=term --cov-report=xml > coverage-output.txt || exit 1
''',
returnStatus: true
)
if (testStatus != 0) {
error "❌ Unit tests failed. Failing pipeline."
}
// Parse coverage and warn if < 80%
def coverageLine = sh(
script: "tail -n 20 coverage-output.txt | grep TOTAL || true",
returnStdout: true
).trim()
if (!coverageLine) {
echo "⚠️ WARNING: TOTAL line not found in coverage output."
} else {
def matcher = coverageLine =~ /TOTAL\\s+\\d+\\s+\\d+\\s+\\d+\\s+(\\d+)%/
if (matcher) {
def coverage = matcher[0][1].toInteger()
if (coverage < 80) {
echo "⚠️ WARNING: Code coverage is ${coverage}%, which is below the 80% threshold."
} else {
echo "✅ Code coverage is ${coverage}%."
}
} else {
echo "⚠️ WARNING: Could not parse coverage percentage."
}
}
}
}
post {
always {
junit 'test-results.xml'
}
}
}
stage('Package Application') {
steps {
sh '''
. ${PYTHON_ENV}/bin/activate
python setup.py sdist bdist_wheel
'''
}
}
stage('Upload to JFrog Artifactory') {
steps {
sh '''
jfrog rt upload dist/*.whl ${ARTIFACTORY_REPO}/
jfrog rt upload dist/*.tar.gz ${ARTIFACTORY_REPO}/
'''
}
}
}
post {
failure {
mail to: 'team@example.com',
subject: "❌ Build Failed: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
body: "Build failed at stage: ${env.STAGE_NAME}\n\nCheck Jenkins logs for details: ${env.BUILD_URL}"
}
}
}
To keep things secure and clean, never hardcode secrets (e.g., API keys, passwords) into your Jenkinsfile
.
✅ Use Jenkins Credentials:
-
Store secrets in Jenkins > Manage Jenkins > Credentials
-
Types:
-
Username & Password
-
Secret Text
-
SSH Key
-
File (e.g., service account JSON)
-
📌 Example:
✅
credentials('id')
injects*_USR
and*_PSW
automatically.
📚 Shared Libraries for Reusable Logic
Jenkins Shared Libraries help avoid repeating code like:
-
Python virtualenv setup
-
Coverage parsing
-
Artifactory upload
-
Checkmarx scanning logic
📁 Directory Structure (Git Repo for Shared Lib):
🧩 Sample vars/pythonSetup.groovy
🔧 Use in Jenkinsfile:
✅ How to Configure Shared Library in Jenkins:
-
Go to Jenkins → Manage Jenkins → Configure System
-
Scroll to Global Pipeline Libraries
-
Add:
-
Name:
my-shared-library
-
Source: Git repo (public or private)
-
Default Version:
main
ormaster
-
📌 TL;DR to Include in Your Jenkinsfile:
You can include this note at the top of your Jenkinsfile:
No comments:
Post a Comment