automated terminal push

This commit is contained in:
lenape
2025-06-29 17:58:23 +00:00
parent 56ffc5a83c
commit fee40bba7b

150
Jenkinsfile vendored
View File

@@ -2,24 +2,12 @@ pipeline {
agent any agent any
environment { environment {
// Non-secret config injected from Jenkins Credentials (Secret Text) BUILD_IMAGE = 'python:3.9-slim'
AWS_REGION = credentials('AWS_REGION') AWS_REGION = 'us-east-1'
AWS_ACCOUNT_ID = credentials('AWS_ACCOUNT_ID') AWS_ACCOUNT_ID = '123456789012'
CODEART_DOMAIN = credentials('CODEART_DOMAIN') CODEART_DOMAIN = 'jacquesingram'
CODEART_REPO = credentials('CODEART_REPO') CODEART_REPO = 'hello-codeartifact'
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 {
@@ -29,22 +17,17 @@ pipeline {
} }
} }
stage('Authenticate & Configure') { stage('Setup') {
steps { steps {
withAWS(credentials: 'jenkins-codeartifact', region: env.AWS_REGION) { script {
script { docker.image(env.BUILD_IMAGE).inside {
// Fetch a short-lived CodeArtifact token sh '''
env.CODEART_TOKEN = sh( pip install --upgrade pip
script: """ pip install build twine pytest
aws codeartifact get-authorization-token \\ if [ -f requirements.txt ]; then
--domain ${env.CODEART_DOMAIN} \\ pip install -r requirements.txt
--domain-owner ${env.AWS_ACCOUNT_ID} \\ fi
--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/"
} }
} }
} }
@@ -53,88 +36,21 @@ pipeline {
stage('Build') { stage('Build') {
steps { steps {
script { script {
// Use Docker for consistent, isolated build environment docker.image(env.BUILD_IMAGE).inside {
docker.image(env.BUILD_IMAGE).inside('-e HOME=/tmp -e PIP_CACHE_DIR=/tmp/.pip') {
sh ''' sh '''
# Corporate standard: CodeArtifact primary, PyPI fallback python -m build
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('-e HOME=/tmp -e PIP_CACHE_DIR=/tmp/.pip') { docker.image(env.BUILD_IMAGE).inside {
sh ''' sh '''
# Corporate standard: CodeArtifact primary, PyPI fallback python -m pytest tests/ --junitxml=test-results.xml || true
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
''' '''
} }
} }
@@ -174,32 +90,18 @@ EOF
} }
} }
} }
}
post { post {
always { always {
// Archive build artifacts // Archive build artifacts
archiveArtifacts artifacts: 'dist/*', allowEmptyArchive: true archiveArtifacts artifacts: 'dist/**', fingerprint: true, allowEmptyArchive: true
// Clean up workspace to prevent credential leakage
cleanWs()
} }
success { success {
echo '✅ Build succeeded and package published to CodeArtifact.' echo 'Pipeline completed successfully!'
// Notify success (Slack, email, etc.)
// slackSend channel: '#builds', color: 'good', message: "✅ ${env.JOB_NAME} - ${env.BUILD_NUMBER} succeeded"
} }
failure { failure {
echo '❌ Build failed — check the console output for errors.' echo 'Pipeline failed!'
// Notify failure
// slackSend channel: '#builds', color: 'danger', message: "❌ ${env.JOB_NAME} - ${env.BUILD_NUMBER} failed"
} }
}
unstable { }
echo '⚠️ Build unstable — tests may have failed.'
}
}