automated terminal push
This commit is contained in:
148
Jenkinsfile
vendored
148
Jenkinsfile
vendored
@@ -2,12 +2,24 @@ pipeline {
|
|||||||
agent any
|
agent any
|
||||||
|
|
||||||
environment {
|
environment {
|
||||||
BUILD_IMAGE = 'python:3.9-slim'
|
// Non-secret config injected from Jenkins Credentials (Secret Text)
|
||||||
AWS_REGION = 'us-east-1'
|
AWS_REGION = credentials('AWS_REGION')
|
||||||
AWS_ACCOUNT_ID = '123456789012'
|
AWS_ACCOUNT_ID = credentials('AWS_ACCOUNT_ID')
|
||||||
CODEART_DOMAIN = 'jacquesingram'
|
CODEART_DOMAIN = credentials('CODEART_DOMAIN')
|
||||||
CODEART_REPO = 'hello-codeartifact'
|
CODEART_REPO = credentials('CODEART_REPO')
|
||||||
CODEART_TOKEN = credentials('codeartifact-token')
|
|
||||||
|
// Build configuration - Corporate-friendly non-root approach
|
||||||
|
PYTHON_VERSION = '3.11-slim'
|
||||||
|
BUILD_IMAGE = "python:${PYTHON_VERSION}"
|
||||||
|
}
|
||||||
|
|
||||||
|
options {
|
||||||
|
// Prevent concurrent builds
|
||||||
|
disableConcurrentBuilds()
|
||||||
|
// Keep build logs for audit
|
||||||
|
buildDiscarder(logRotator(numToKeepStr: '50'))
|
||||||
|
// Timeout protection
|
||||||
|
timeout(time: 30, unit: 'MINUTES')
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
@@ -17,17 +29,22 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('Setup') {
|
stage('Authenticate & Configure') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
withAWS(credentials: 'jenkins-codeartifact', region: env.AWS_REGION) {
|
||||||
docker.image(env.BUILD_IMAGE).inside {
|
script {
|
||||||
sh '''
|
// Fetch a short-lived CodeArtifact token
|
||||||
pip install --upgrade pip
|
env.CODEART_TOKEN = sh(
|
||||||
pip install build twine pytest
|
script: """
|
||||||
if [ -f requirements.txt ]; then
|
aws codeartifact get-authorization-token \\
|
||||||
pip install -r requirements.txt
|
--domain ${env.CODEART_DOMAIN} \\
|
||||||
fi
|
--domain-owner ${env.AWS_ACCOUNT_ID} \\
|
||||||
'''
|
--query authorizationToken --output text
|
||||||
|
""", returnStdout: true
|
||||||
|
).trim()
|
||||||
|
|
||||||
|
// Store repository URL for Docker container
|
||||||
|
env.CODEART_URL = "https://aws:${env.CODEART_TOKEN}@${env.CODEART_DOMAIN}-${env.AWS_ACCOUNT_ID}.d.codeartifact.${env.AWS_REGION}.amazonaws.com/pypi/${env.CODEART_REPO}/simple/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,21 +53,88 @@ pipeline {
|
|||||||
stage('Build') {
|
stage('Build') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
docker.image(env.BUILD_IMAGE).inside {
|
// Use Docker for consistent, isolated build environment
|
||||||
|
docker.image(env.BUILD_IMAGE).inside('-e HOME=/tmp -e PIP_CACHE_DIR=/tmp/.pip') {
|
||||||
sh '''
|
sh '''
|
||||||
python -m build
|
# Corporate standard: CodeArtifact primary, PyPI fallback
|
||||||
|
export PIP_INDEX_URL="${CODEART_URL}"
|
||||||
|
export PIP_EXTRA_INDEX_URL="https://pypi.org/simple/"
|
||||||
|
|
||||||
|
# Install build dependencies
|
||||||
|
pip install --upgrade setuptools wheel twine
|
||||||
|
|
||||||
|
# Build the package
|
||||||
|
python3 setup.py sdist bdist_wheel
|
||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stage('Security Scan') {
|
||||||
|
parallel {
|
||||||
|
stage('Trivy Filesystem Scan') {
|
||||||
|
steps {
|
||||||
|
sh '''
|
||||||
|
docker run --rm -v ${WORKSPACE}:/project \\
|
||||||
|
aquasec/trivy:latest fs \\
|
||||||
|
--severity HIGH,CRITICAL \\
|
||||||
|
--exit-code 1 \\
|
||||||
|
--format json \\
|
||||||
|
--output trivy-fs-report.json \\
|
||||||
|
/project
|
||||||
|
'''
|
||||||
|
|
||||||
|
// Archive security scan results
|
||||||
|
archiveArtifacts artifacts: 'trivy-fs-report.json', allowEmptyArchive: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Package Vulnerability Scan') {
|
||||||
|
when {
|
||||||
|
// Only scan if build artifacts exist
|
||||||
|
expression { fileExists('dist/*.whl') }
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
docker.image(env.BUILD_IMAGE).inside('-e HOME=/tmp -e PIP_CACHE_DIR=/tmp/.pip') {
|
||||||
|
sh '''
|
||||||
|
# Corporate standard: CodeArtifact primary, PyPI fallback
|
||||||
|
export PIP_INDEX_URL="${CODEART_URL}"
|
||||||
|
export PIP_EXTRA_INDEX_URL="https://pypi.org/simple/"
|
||||||
|
|
||||||
|
pip install safety
|
||||||
|
safety check --json --output safety-report.json || true
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
archiveArtifacts artifacts: 'safety-report.json', allowEmptyArchive: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stage('Test') {
|
stage('Test') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
docker.image(env.BUILD_IMAGE).inside {
|
docker.image(env.BUILD_IMAGE).inside('-e HOME=/tmp -e PIP_CACHE_DIR=/tmp/.pip') {
|
||||||
sh '''
|
sh '''
|
||||||
python -m pytest tests/ --junitxml=test-results.xml || true
|
# Corporate standard: CodeArtifact primary, PyPI fallback
|
||||||
|
export PIP_INDEX_URL="${CODEART_URL}"
|
||||||
|
export PIP_EXTRA_INDEX_URL="https://pypi.org/simple/"
|
||||||
|
|
||||||
|
# Install test dependencies if they exist
|
||||||
|
if [ -f requirements-test.txt ]; then
|
||||||
|
pip install -r requirements-test.txt
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install the built package for testing
|
||||||
|
pip install dist/*.whl
|
||||||
|
|
||||||
|
# Run tests if they exist
|
||||||
|
if [ -f pytest.ini ] || [ -d tests ]; then
|
||||||
|
python -m pytest --junitxml=test-results.xml || true
|
||||||
|
fi
|
||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,18 +174,32 @@ EOF
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
post {
|
post {
|
||||||
always {
|
always {
|
||||||
// Archive build artifacts
|
// Archive build artifacts
|
||||||
archiveArtifacts artifacts: 'dist/**', fingerprint: true, allowEmptyArchive: true
|
archiveArtifacts artifacts: 'dist/*', allowEmptyArchive: true
|
||||||
|
|
||||||
|
// Clean up workspace to prevent credential leakage
|
||||||
|
cleanWs()
|
||||||
}
|
}
|
||||||
|
|
||||||
success {
|
success {
|
||||||
echo 'Pipeline completed successfully!'
|
echo '✅ Build succeeded and package published to CodeArtifact.'
|
||||||
|
|
||||||
|
// Notify success (Slack, email, etc.)
|
||||||
|
// slackSend channel: '#builds', color: 'good', message: "✅ ${env.JOB_NAME} - ${env.BUILD_NUMBER} succeeded"
|
||||||
}
|
}
|
||||||
|
|
||||||
failure {
|
failure {
|
||||||
echo 'Pipeline failed!'
|
echo '❌ Build failed — check the console output for errors.'
|
||||||
|
|
||||||
|
// Notify failure
|
||||||
|
// slackSend channel: '#builds', color: 'danger', message: "❌ ${env.JOB_NAME} - ${env.BUILD_NUMBER} failed"
|
||||||
|
}
|
||||||
|
|
||||||
|
unstable {
|
||||||
|
echo '⚠️ Build unstable — tests may have failed.'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
Reference in New Issue
Block a user