Jenkins CI/CD Integration

Jenkins provides enterprise-grade CI/CD capabilities that integrate seamlessly with CloudRepo for publishing and consuming artifacts across all supported package types.

This guide covers complete integration patterns for Maven, Gradle, and Python projects using both Freestyle jobs and Pipeline configurations, along with advanced patterns and security best practices.

Benefits & Overview

Why Use CloudRepo with Jenkins

  • Cost Effective: Save 90%+ compared to JFrog Artifactory with no egress fees

  • Native Integration: Works seamlessly with all Jenkins job types and build tools

  • Secure: Leverage Jenkins Credentials Manager for secure credential storage

  • Scalable: Handle everything from small libraries to enterprise deployments

  • Support Included: All plans include professional support

Repository URL Format

All CloudRepo repositories follow this URL pattern:

https://[organization-id].mycloudrepo.io/repositories/[repository-id]

Replace [organization-id] and [repository-id] with your actual values throughout this guide.

Prerequisites

Jenkins Setup Requirements

Minimum Jenkins Version: 2.387.0 or higher (LTS recommended)

Required Plugins:

- Credentials Plugin (2.6.0+)
- Credentials Binding Plugin (1.27+)
- Config File Provider Plugin (3.11.0+)
- Pipeline (2.6+)
- Pipeline: Groovy (3656.v4de5f823b_a_ef+)

For Maven projects:
- Maven Integration Plugin (3.22+)

For Gradle projects:
- Gradle Plugin (2.8+)

For Python projects:
- Python Plugin (optional, for virtual environment management)

Installing Plugins via Jenkins UI:

  1. Navigate to Manage JenkinsManage Plugins

  2. Click the Available tab

  3. Search for and select the required plugins

  4. Click Install without restart

Installing Plugins via Jenkins CLI:

# Download Jenkins CLI
wget http://your-jenkins-url/jnlpJars/jenkins-cli.jar

# Install plugins
java -jar jenkins-cli.jar -s http://your-jenkins-url/ install-plugin \
  credentials credentials-binding config-file-provider \
  workflow-aggregator maven-plugin gradle

CloudRepo Account Setup

Before configuring Jenkins, ensure you have:

  1. A CloudRepo organization account

  2. At least one repository created (Maven, Python, or Raw)

  3. A user account with appropriate permissions:

    • Read permission for consuming artifacts

    • Write permission for publishing artifacts

    • Admin permission for repository management

  4. Your organization ID and repository ID from the CloudRepo dashboard

Authentication Configuration

Jenkins Credentials Manager

CloudRepo supports multiple authentication methods through Jenkins Credentials Manager.

Creating Username/Password Credentials:

  1. Navigate to Manage JenkinsManage Credentials

  2. Select the appropriate domain (typically (global))

  3. Click Add Credentials

  4. Configure the credential:

    Kind: Username with password
    Scope: Global
    Username: your-cloudrepo-username
    Password: your-cloudrepo-password
    ID: cloudrepo-credentials
    Description: CloudRepo Authentication
    

Using API Tokens (Recommended for automation):

  1. Generate an API token in CloudRepo:

    • Log into CloudRepo dashboard

    • Navigate to Account SettingsAPI Tokens

    • Click Generate New Token

    • Copy the generated token

  2. Create Jenkins credentials:

    Kind: Username with password
    Scope: Global
    Username: your-cloudrepo-username
    Password: [paste-api-token-here]
    ID: cloudrepo-api-token
    Description: CloudRepo API Token
    

Credentials Security Best Practices:

Warning

Never hard-code credentials in Jenkinsfiles or job configurations.

  • Use folder-level credentials for multi-team environments

  • Implement least-privilege access control

  • Rotate API tokens regularly

  • Use Jenkins RBAC to control credential access

  • Enable audit logging for credential usage

Maven Projects

Freestyle Job Configuration

Step 1: Create New Freestyle Project

  1. Click New Item → Enter job name → Select Freestyle project

  2. Configure Source Code Management (Git, SVN, etc.)

Step 2: Configure Maven Settings

Using Config File Provider plugin:

  1. Navigate to Manage JenkinsManaged files

  2. Click Add a new ConfigMaven settings.xml

  3. Configure the settings.xml:

Maven settings.xml for CloudRepo
 1<?xml version="1.0" encoding="UTF-8"?>
 2<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
 5                              http://maven.apache.org/xsd/settings-1.0.0.xsd">
 6
 7  <servers>
 8    <server>
 9      <id>cloudrepo-releases</id>
10      <username>${env.CLOUDREPO_USERNAME}</username>
11      <password>${env.CLOUDREPO_PASSWORD}</password>
12    </server>
13    <server>
14      <id>cloudrepo-snapshots</id>
15      <username>${env.CLOUDREPO_USERNAME}</username>
16      <password>${env.CLOUDREPO_PASSWORD}</password>
17    </server>
18  </servers>
19
20  <profiles>
21    <profile>
22      <id>cloudrepo</id>
23      <repositories>
24        <repository>
25          <id>cloudrepo-releases</id>
26          <url>https://your-org.mycloudrepo.io/repositories/releases</url>
27          <releases>
28            <enabled>true</enabled>
29          </releases>
30          <snapshots>
31            <enabled>false</enabled>
32          </snapshots>
33        </repository>
34        <repository>
35          <id>cloudrepo-snapshots</id>
36          <url>https://your-org.mycloudrepo.io/repositories/snapshots</url>
37          <releases>
38            <enabled>false</enabled>
39          </releases>
40          <snapshots>
41            <enabled>true</enabled>
42          </snapshots>
43        </repository>
44      </repositories>
45    </profile>
46  </profiles>
47
48  <activeProfiles>
49    <activeProfile>cloudrepo</activeProfile>
50  </activeProfiles>
51</settings>

Step 3: Configure Build Environment

  1. Check Use secret text(s) or file(s)

  2. Add Username and password binding:

    • Username Variable: CLOUDREPO_USERNAME

    • Password Variable: CLOUDREPO_PASSWORD

    • Credentials: Select your CloudRepo credentials

  3. Add Config file:

    • File: Select your Maven settings.xml

    • Variable: MAVEN_SETTINGS

Step 4: Configure Build Steps

Add Invoke top-level Maven targets:

# For deployment
clean deploy -s ${MAVEN_SETTINGS}

# For just building
clean package -s ${MAVEN_SETTINGS}

Pipeline Configuration (Declarative)

Declarative Pipeline - Maven with CloudRepo
 1pipeline {
 2    agent any
 3
 4    tools {
 5        maven 'Maven-3.9.5'
 6        jdk 'JDK-17'
 7    }
 8
 9    environment {
10        CLOUDREPO_ORG = 'your-org'
11        CLOUDREPO_RELEASES = "https://${CLOUDREPO_ORG}.mycloudrepo.io/repositories/maven-releases"
12        CLOUDREPO_SNAPSHOTS = "https://${CLOUDREPO_ORG}.mycloudrepo.io/repositories/maven-snapshots"
13    }
14
15    stages {
16        stage('Checkout') {
17            steps {
18                checkout scm
19            }
20        }
21
22        stage('Build') {
23            steps {
24                withCredentials([usernamePassword(
25                    credentialsId: 'cloudrepo-credentials',
26                    usernameVariable: 'CLOUDREPO_USERNAME',
27                    passwordVariable: 'CLOUDREPO_PASSWORD'
28                )]) {
29                    configFileProvider([configFile(
30                        fileId: 'cloudrepo-maven-settings',
31                        variable: 'MAVEN_SETTINGS'
32                    )]) {
33                        sh 'mvn clean compile -s $MAVEN_SETTINGS'
34                    }
35                }
36            }
37        }
38
39        stage('Test') {
40            steps {
41                withCredentials([usernamePassword(
42                    credentialsId: 'cloudrepo-credentials',
43                    usernameVariable: 'CLOUDREPO_USERNAME',
44                    passwordVariable: 'CLOUDREPO_PASSWORD'
45                )]) {
46                    configFileProvider([configFile(
47                        fileId: 'cloudrepo-maven-settings',
48                        variable: 'MAVEN_SETTINGS'
49                    )]) {
50                        sh 'mvn test -s $MAVEN_SETTINGS'
51                    }
52                }
53            }
54            post {
55                always {
56                    junit '**/target/surefire-reports/*.xml'
57                }
58            }
59        }
60
61        stage('Deploy to CloudRepo') {
62            when {
63                anyOf {
64                    branch 'main'
65                    branch 'master'
66                    branch 'release/*'
67                }
68            }
69            steps {
70                withCredentials([usernamePassword(
71                    credentialsId: 'cloudrepo-credentials',
72                    usernameVariable: 'CLOUDREPO_USERNAME',
73                    passwordVariable: 'CLOUDREPO_PASSWORD'
74                )]) {
75                    configFileProvider([configFile(
76                        fileId: 'cloudrepo-maven-settings',
77                        variable: 'MAVEN_SETTINGS'
78                    )]) {
79                        sh 'mvn deploy -DskipTests -s $MAVEN_SETTINGS'
80                    }
81                }
82            }
83        }
84    }
85
86    post {
87        success {
88            echo "Successfully deployed to CloudRepo"
89        }
90        failure {
91            emailext (
92                subject: "Build Failed: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
93                body: "The build failed. Please check Jenkins for details.",
94                to: 'team@example.com'
95            )
96        }
97    }
98}

Pipeline Configuration (Scripted)

Scripted Pipeline - Maven with CloudRepo
 1node {
 2    def mvnHome = tool 'Maven-3.9.5'
 3    def javaHome = tool 'JDK-17'
 4
 5    env.PATH = "${mvnHome}/bin:${javaHome}/bin:${env.PATH}"
 6    env.JAVA_HOME = "${javaHome}"
 7
 8    try {
 9        stage('Checkout') {
10            checkout scm
11        }
12
13        stage('Build and Test') {
14            withCredentials([usernamePassword(
15                credentialsId: 'cloudrepo-credentials',
16                usernameVariable: 'CLOUDREPO_USERNAME',
17                passwordVariable: 'CLOUDREPO_PASSWORD'
18            )]) {
19                configFileProvider([configFile(
20                    fileId: 'cloudrepo-maven-settings',
21                    variable: 'MAVEN_SETTINGS'
22                )]) {
23                    sh "mvn clean test -s ${MAVEN_SETTINGS}"
24
25                    // Archive test results
26                    junit '**/target/surefire-reports/*.xml'
27                }
28            }
29        }
30
31        stage('Deploy to CloudRepo') {
32            if (env.BRANCH_NAME == 'main' ||
33                env.BRANCH_NAME == 'master' ||
34                env.BRANCH_NAME.startsWith('release/')) {
35
36                withCredentials([usernamePassword(
37                    credentialsId: 'cloudrepo-credentials',
38                    usernameVariable: 'CLOUDREPO_USERNAME',
39                    passwordVariable: 'CLOUDREPO_PASSWORD'
40                )]) {
41                    configFileProvider([configFile(
42                        fileId: 'cloudrepo-maven-settings',
43                        variable: 'MAVEN_SETTINGS'
44                    )]) {
45                        sh "mvn deploy -DskipTests -s ${MAVEN_SETTINGS}"
46
47                        // Parse version from pom.xml
48                        def pom = readMavenPom file: 'pom.xml'
49                        currentBuild.description = "Deployed ${pom.version} to CloudRepo"
50                    }
51                }
52            } else {
53                echo "Skipping deployment for branch: ${env.BRANCH_NAME}"
54            }
55        }
56
57    } catch (Exception e) {
58        currentBuild.result = 'FAILURE'
59        throw e
60    } finally {
61        // Clean workspace optionally
62        if (currentBuild.result == 'FAILURE') {
63            cleanWs()
64        }
65    }
66}

Maven pom.xml Configuration

Configure your pom.xml to use CloudRepo repositories:

Maven pom.xml - Distribution Management
 1<project>
 2    <!-- ... other configuration ... -->
 3
 4    <distributionManagement>
 5        <repository>
 6            <id>cloudrepo-releases</id>
 7            <url>https://your-org.mycloudrepo.io/repositories/maven-releases</url>
 8        </repository>
 9        <snapshotRepository>
10            <id>cloudrepo-snapshots</id>
11            <url>https://your-org.mycloudrepo.io/repositories/maven-snapshots</url>
12        </snapshotRepository>
13    </distributionManagement>
14
15    <!-- Optional: Configure for dependency resolution -->
16    <repositories>
17        <repository>
18            <id>cloudrepo-releases</id>
19            <url>https://your-org.mycloudrepo.io/repositories/maven-releases</url>
20            <releases>
21                <enabled>true</enabled>
22            </releases>
23            <snapshots>
24                <enabled>false</enabled>
25            </snapshots>
26        </repository>
27        <repository>
28            <id>cloudrepo-snapshots</id>
29            <url>https://your-org.mycloudrepo.io/repositories/maven-snapshots</url>
30            <releases>
31                <enabled>false</enabled>
32            </releases>
33            <snapshots>
34                <enabled>true</enabled>
35                <updatePolicy>always</updatePolicy>
36            </snapshots>
37        </repository>
38    </repositories>
39</project>

Gradle Projects

Freestyle Job Configuration

Step 1: Create Gradle Properties File

  1. Navigate to Manage JenkinsManaged files

  2. Add new Config → Custom file

  3. Name: gradle.properties

  4. Content:

gradle.properties for CloudRepo
1cloudrepoUsername=${CLOUDREPO_USERNAME}
2cloudrepoPassword=${CLOUDREPO_PASSWORD}
3cloudrepoReleasesUrl=https://your-org.mycloudrepo.io/repositories/maven-releases
4cloudrepoSnapshotsUrl=https://your-org.mycloudrepo.io/repositories/maven-snapshots

Step 2: Configure Build Environment

  1. Check Use secret text(s) or file(s)

  2. Add credentials binding (same as Maven)

  3. Add gradle.properties as config file

Step 3: Configure Build Step

Add Invoke Gradle script:

# Tasks
clean build publish

# Switches
--gradle-user-home ${WORKSPACE}/.gradle

Pipeline Configuration (Declarative)

Declarative Pipeline - Gradle with CloudRepo
 1pipeline {
 2    agent any
 3
 4    tools {
 5        gradle 'Gradle-8.5'
 6        jdk 'JDK-17'
 7    }
 8
 9    environment {
10        CLOUDREPO_ORG = 'your-org'
11        CLOUDREPO_RELEASES = "https://${CLOUDREPO_ORG}.mycloudrepo.io/repositories/maven-releases"
12        CLOUDREPO_SNAPSHOTS = "https://${CLOUDREPO_ORG}.mycloudrepo.io/repositories/maven-snapshots"
13    }
14
15    stages {
16        stage('Checkout') {
17            steps {
18                checkout scm
19            }
20        }
21
22        stage('Build') {
23            steps {
24                withCredentials([usernamePassword(
25                    credentialsId: 'cloudrepo-credentials',
26                    usernameVariable: 'CLOUDREPO_USERNAME',
27                    passwordVariable: 'CLOUDREPO_PASSWORD'
28                )]) {
29                    sh '''
30                        ./gradlew clean build \
31                            -PcloudrepoUsername=$CLOUDREPO_USERNAME \
32                            -PcloudrepoPassword=$CLOUDREPO_PASSWORD
33                    '''
34                }
35            }
36        }
37
38        stage('Test') {
39            steps {
40                withCredentials([usernamePassword(
41                    credentialsId: 'cloudrepo-credentials',
42                    usernameVariable: 'CLOUDREPO_USERNAME',
43                    passwordVariable: 'CLOUDREPO_PASSWORD'
44                )]) {
45                    sh '''
46                        ./gradlew test \
47                            -PcloudrepoUsername=$CLOUDREPO_USERNAME \
48                            -PcloudrepoPassword=$CLOUDREPO_PASSWORD
49                    '''
50                }
51            }
52            post {
53                always {
54                    junit '**/build/test-results/test/*.xml'
55                    publishHTML([
56                        reportDir: 'build/reports/tests/test',
57                        reportFiles: 'index.html',
58                        reportName: 'Test Report'
59                    ])
60                }
61            }
62        }
63
64        stage('Publish to CloudRepo') {
65            when {
66                anyOf {
67                    branch 'main'
68                    branch 'master'
69                    branch 'release/*'
70                }
71            }
72            steps {
73                withCredentials([usernamePassword(
74                    credentialsId: 'cloudrepo-credentials',
75                    usernameVariable: 'CLOUDREPO_USERNAME',
76                    passwordVariable: 'CLOUDREPO_PASSWORD'
77                )]) {
78                    sh '''
79                        ./gradlew publish \
80                            -PcloudrepoUsername=$CLOUDREPO_USERNAME \
81                            -PcloudrepoPassword=$CLOUDREPO_PASSWORD
82                    '''
83                }
84            }
85        }
86    }
87
88    post {
89        always {
90            cleanWs()
91        }
92    }
93}

Gradle build.gradle Configuration

Configure your build.gradle (Groovy DSL):

build.gradle - CloudRepo Publishing (Groovy)
 1plugins {
 2    id 'java'
 3    id 'maven-publish'
 4}
 5
 6group = 'com.example'
 7version = '1.0.0'
 8
 9repositories {
10    mavenCentral()
11
12    // CloudRepo repositories for dependencies
13    maven {
14        url "https://your-org.mycloudrepo.io/repositories/maven-releases"
15        credentials {
16            username = project.findProperty("cloudrepoUsername") ?: System.getenv("CLOUDREPO_USERNAME")
17            password = project.findProperty("cloudrepoPassword") ?: System.getenv("CLOUDREPO_PASSWORD")
18        }
19    }
20
21    maven {
22        url "https://your-org.mycloudrepo.io/repositories/maven-snapshots"
23        credentials {
24            username = project.findProperty("cloudrepoUsername") ?: System.getenv("CLOUDREPO_USERNAME")
25            password = project.findProperty("cloudrepoPassword") ?: System.getenv("CLOUDREPO_PASSWORD")
26        }
27    }
28}
29
30publishing {
31    publications {
32        maven(MavenPublication) {
33            from components.java
34
35            pom {
36                name = 'My Library'
37                description = 'A description of my library'
38                url = 'https://github.com/example/my-library'
39            }
40        }
41    }
42
43    repositories {
44        maven {
45            def releasesRepoUrl = "https://your-org.mycloudrepo.io/repositories/maven-releases"
46            def snapshotsRepoUrl = "https://your-org.mycloudrepo.io/repositories/maven-snapshots"
47            url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
48
49            credentials {
50                username = project.findProperty("cloudrepoUsername") ?: System.getenv("CLOUDREPO_USERNAME")
51                password = project.findProperty("cloudrepoPassword") ?: System.getenv("CLOUDREPO_PASSWORD")
52            }
53        }
54    }
55}

Or using Kotlin DSL (build.gradle.kts):

build.gradle.kts - CloudRepo Publishing (Kotlin)
 1plugins {
 2    java
 3    `maven-publish`
 4}
 5
 6group = "com.example"
 7version = "1.0.0"
 8
 9repositories {
10    mavenCentral()
11
12    maven {
13        url = uri("https://your-org.mycloudrepo.io/repositories/maven-releases")
14        credentials {
15            username = project.findProperty("cloudrepoUsername") as String?
16                ?: System.getenv("CLOUDREPO_USERNAME")
17            password = project.findProperty("cloudrepoPassword") as String?
18                ?: System.getenv("CLOUDREPO_PASSWORD")
19        }
20    }
21}
22
23publishing {
24    publications {
25        create<MavenPublication>("maven") {
26            from(components["java"])
27
28            pom {
29                name.set("My Library")
30                description.set("A description of my library")
31                url.set("https://github.com/example/my-library")
32            }
33        }
34    }
35
36    repositories {
37        maven {
38            val releasesRepoUrl = "https://your-org.mycloudrepo.io/repositories/maven-releases"
39            val snapshotsRepoUrl = "https://your-org.mycloudrepo.io/repositories/maven-snapshots"
40            url = uri(if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl)
41
42            credentials {
43                username = project.findProperty("cloudrepoUsername") as String?
44                    ?: System.getenv("CLOUDREPO_USERNAME")
45                password = project.findProperty("cloudrepoPassword") as String?
46                    ?: System.getenv("CLOUDREPO_PASSWORD")
47            }
48        }
49    }
50}

Python Projects

Using pip and setuptools

Declarative Pipeline - Python with pip
 1pipeline {
 2    agent any
 3
 4    environment {
 5        CLOUDREPO_ORG = 'your-org'
 6        CLOUDREPO_PYPI = "https://${CLOUDREPO_ORG}.mycloudrepo.io/repositories/python"
 7    }
 8
 9    stages {
10        stage('Setup Python Environment') {
11            steps {
12                sh '''
13                    python3 -m venv venv
14                    . venv/bin/activate
15                    pip install --upgrade pip setuptools wheel twine
16                '''
17            }
18        }
19
20        stage('Install Dependencies') {
21            steps {
22                withCredentials([usernamePassword(
23                    credentialsId: 'cloudrepo-credentials',
24                    usernameVariable: 'CLOUDREPO_USERNAME',
25                    passwordVariable: 'CLOUDREPO_PASSWORD'
26                )]) {
27                    sh '''
28                        . venv/bin/activate
29                        pip install --index-url https://${CLOUDREPO_USERNAME}:${CLOUDREPO_PASSWORD}@${CLOUDREPO_ORG}.mycloudrepo.io/repositories/python/simple -r requirements.txt
30                    '''
31                }
32            }
33        }
34
35        stage('Run Tests') {
36            steps {
37                sh '''
38                    . venv/bin/activate
39                    pip install pytest pytest-cov
40                    pytest --cov=mypackage --cov-report=xml --cov-report=html
41                '''
42            }
43            post {
44                always {
45                    publishHTML([
46                        reportDir: 'htmlcov',
47                        reportFiles: 'index.html',
48                        reportName: 'Coverage Report'
49                    ])
50                    junit 'test-results.xml'
51                }
52            }
53        }
54
55        stage('Build Package') {
56            steps {
57                sh '''
58                    . venv/bin/activate
59                    python setup.py sdist bdist_wheel
60                '''
61            }
62        }
63
64        stage('Publish to CloudRepo') {
65            when {
66                branch 'main'
67            }
68            steps {
69                withCredentials([usernamePassword(
70                    credentialsId: 'cloudrepo-credentials',
71                    usernameVariable: 'CLOUDREPO_USERNAME',
72                    passwordVariable: 'CLOUDREPO_PASSWORD'
73                )]) {
74                    sh '''
75                        . venv/bin/activate
76                        twine upload \
77                            --repository-url ${CLOUDREPO_PYPI} \
78                            --username ${CLOUDREPO_USERNAME} \
79                            --password ${CLOUDREPO_PASSWORD} \
80                            dist/*
81                    '''
82                }
83            }
84        }
85    }
86
87    post {
88        always {
89            cleanWs()
90        }
91    }
92}

Poetry Configuration in Jenkins

Declarative Pipeline - Python with Poetry
 1pipeline {
 2    agent any
 3
 4    environment {
 5        CLOUDREPO_ORG = 'your-org'
 6        POETRY_HOME = "${WORKSPACE}/.poetry"
 7        PATH = "${POETRY_HOME}/bin:${PATH}"
 8    }
 9
10    stages {
11        stage('Install Poetry') {
12            steps {
13                sh '''
14                    curl -sSL https://install.python-poetry.org | python3 -
15                    poetry --version
16                '''
17            }
18        }
19
20        stage('Configure Poetry for CloudRepo') {
21            steps {
22                withCredentials([usernamePassword(
23                    credentialsId: 'cloudrepo-credentials',
24                    usernameVariable: 'CLOUDREPO_USERNAME',
25                    passwordVariable: 'CLOUDREPO_PASSWORD'
26                )]) {
27                    sh '''
28                        # Configure CloudRepo as source
29                        poetry source add cloudrepo https://${CLOUDREPO_ORG}.mycloudrepo.io/repositories/python/simple
30                        poetry config http-basic.cloudrepo ${CLOUDREPO_USERNAME} ${CLOUDREPO_PASSWORD}
31
32                        # Configure for publishing
33                        poetry config repositories.cloudrepo https://${CLOUDREPO_ORG}.mycloudrepo.io/repositories/python
34                    '''
35                }
36            }
37        }
38
39        stage('Install Dependencies') {
40            steps {
41                sh 'poetry install'
42            }
43        }
44
45        stage('Run Tests') {
46            steps {
47                sh '''
48                    poetry run pytest --cov=mypackage --cov-report=xml
49                    poetry run black --check .
50                    poetry run mypy mypackage
51                '''
52            }
53        }
54
55        stage('Build and Publish') {
56            when {
57                branch 'main'
58            }
59            steps {
60                withCredentials([usernamePassword(
61                    credentialsId: 'cloudrepo-credentials',
62                    usernameVariable: 'CLOUDREPO_USERNAME',
63                    passwordVariable: 'CLOUDREPO_PASSWORD'
64                )]) {
65                    sh '''
66                        poetry build
67                        poetry publish -r cloudrepo -u ${CLOUDREPO_USERNAME} -p ${CLOUDREPO_PASSWORD}
68                    '''
69                }
70            }
71        }
72    }
73}

Python Package Configuration

setup.py configuration:

setup.py - Python Package Configuration
 1from setuptools import setup, find_packages
 2
 3setup(
 4    name="my-package",
 5    version="1.0.0",
 6    packages=find_packages(),
 7    install_requires=[
 8        "requests>=2.28.0",
 9        "pandas>=1.5.0",
10    ],
11    author="Your Name",
12    author_email="your.email@example.com",
13    description="A short description of your package",
14    long_description=open("README.md").read(),
15    long_description_content_type="text/markdown",
16    url="https://github.com/yourusername/my-package",
17    classifiers=[
18        "Programming Language :: Python :: 3",
19        "License :: OSI Approved :: MIT License",
20        "Operating System :: OS Independent",
21    ],
22    python_requires=">=3.8",
23)

pyproject.toml for Poetry:

pyproject.toml - Poetry Configuration
 1[tool.poetry]
 2name = "my-package"
 3version = "1.0.0"
 4description = "A short description of your package"
 5authors = ["Your Name <your.email@example.com>"]
 6readme = "README.md"
 7packages = [{include = "my_package"}]
 8
 9[tool.poetry.dependencies]
10python = "^3.8"
11requests = "^2.28.0"
12pandas = "^1.5.0"
13
14[tool.poetry.group.dev.dependencies]
15pytest = "^7.2.0"
16pytest-cov = "^4.0.0"
17black = "^23.0.0"
18mypy = "^1.0.0"
19
20[[tool.poetry.source]]
21name = "cloudrepo"
22url = "https://your-org.mycloudrepo.io/repositories/python/simple"
23priority = "supplemental"
24
25[build-system]
26requires = ["poetry-core"]
27build-backend = "poetry.core.masonry.api"

Multi-Branch Pipelines

Configuration for Feature Branches

Multi-branch pipelines automatically create jobs for each branch in your repository:

Jenkinsfile - Multi-Branch Pipeline with Branch Logic
  1pipeline {
  2    agent any
  3
  4    environment {
  5        CLOUDREPO_ORG = 'your-org'
  6        // Determine repository based on branch
  7        CLOUDREPO_REPO = "${env.BRANCH_NAME.startsWith('release/') ? 'releases' : 'snapshots'}"
  8        CLOUDREPO_URL = "https://${CLOUDREPO_ORG}.mycloudrepo.io/repositories/maven-${CLOUDREPO_REPO}"
  9    }
 10
 11    stages {
 12        stage('Build Info') {
 13            steps {
 14                script {
 15                    // Set version based on branch
 16                    def baseVersion = readMavenPom().version.replace('-SNAPSHOT', '')
 17
 18                    if (env.BRANCH_NAME == 'main' || env.BRANCH_NAME == 'master') {
 19                        env.PROJECT_VERSION = "${baseVersion}-SNAPSHOT"
 20                        env.DEPLOY_REPO = "snapshots"
 21                    } else if (env.BRANCH_NAME.startsWith('release/')) {
 22                        env.PROJECT_VERSION = baseVersion
 23                        env.DEPLOY_REPO = "releases"
 24                    } else if (env.BRANCH_NAME.startsWith('feature/')) {
 25                        env.PROJECT_VERSION = "${baseVersion}-${env.BRANCH_NAME.replace('/', '-')}-SNAPSHOT"
 26                        env.DEPLOY_REPO = "feature-snapshots"
 27                    } else {
 28                        env.PROJECT_VERSION = "${baseVersion}-${env.BUILD_NUMBER}-SNAPSHOT"
 29                        env.DEPLOY_REPO = "snapshots"
 30                    }
 31
 32                    currentBuild.displayName = "#${BUILD_NUMBER} - ${env.PROJECT_VERSION}"
 33                    currentBuild.description = "Branch: ${env.BRANCH_NAME}"
 34                }
 35            }
 36        }
 37
 38        stage('Build and Test') {
 39            steps {
 40                withCredentials([usernamePassword(
 41                    credentialsId: 'cloudrepo-credentials',
 42                    usernameVariable: 'CLOUDREPO_USERNAME',
 43                    passwordVariable: 'CLOUDREPO_PASSWORD'
 44                )]) {
 45                    sh """
 46                        mvn clean test \
 47                            -Drevision=${env.PROJECT_VERSION} \
 48                            -DcloudrepoUsername=${CLOUDREPO_USERNAME} \
 49                            -DcloudrepoPassword=${CLOUDREPO_PASSWORD}
 50                    """
 51                }
 52            }
 53        }
 54
 55        stage('Deploy') {
 56            when {
 57                anyOf {
 58                    branch 'main'
 59                    branch 'master'
 60                    branch 'develop'
 61                    branch 'release/*'
 62                    branch 'hotfix/*'
 63                }
 64            }
 65            steps {
 66                withCredentials([usernamePassword(
 67                    credentialsId: 'cloudrepo-credentials',
 68                    usernameVariable: 'CLOUDREPO_USERNAME',
 69                    passwordVariable: 'CLOUDREPO_PASSWORD'
 70                )]) {
 71                    sh """
 72                        mvn deploy \
 73                            -Drevision=${env.PROJECT_VERSION} \
 74                            -DaltDeploymentRepository=cloudrepo::https://${CLOUDREPO_ORG}.mycloudrepo.io/repositories/maven-${env.DEPLOY_REPO} \
 75                            -DcloudrepoUsername=${CLOUDREPO_USERNAME} \
 76                            -DcloudrepoPassword=${CLOUDREPO_PASSWORD}
 77                    """
 78                }
 79            }
 80        }
 81
 82        stage('Tag Release') {
 83            when {
 84                branch 'release/*'
 85            }
 86            steps {
 87                script {
 88                    sshagent(credentials: ['git-ssh-key']) {
 89                        sh """
 90                            git tag -a v${env.PROJECT_VERSION} -m "Release version ${env.PROJECT_VERSION}"
 91                            git push origin v${env.PROJECT_VERSION}
 92                        """
 93                    }
 94                }
 95            }
 96        }
 97    }
 98
 99    post {
100        success {
101            script {
102                if (env.BRANCH_NAME == 'release/*') {
103                    emailext(
104                        subject: "Release Deployed: ${env.PROJECT_VERSION}",
105                        body: "Version ${env.PROJECT_VERSION} has been successfully deployed to CloudRepo.",
106                        to: 'release-team@example.com'
107                    )
108                }
109            }
110        }
111    }
112}

Branch-Specific Repository Configuration

Configure different repositories for different branches:

Branch-Based Repository Selection
 1def getCloudRepoUrl(String branchName, String orgId) {
 2    def baseUrl = "https://${orgId}.mycloudrepo.io/repositories"
 3
 4    switch(branchName) {
 5        case ~/^(main|master)$/:
 6            return "${baseUrl}/maven-snapshots"
 7        case ~/^release\/.*/:
 8            return "${baseUrl}/maven-releases"
 9        case ~/^feature\/.*/:
10            return "${baseUrl}/maven-feature-snapshots"
11        case ~/^hotfix\/.*/:
12            return "${baseUrl}/maven-hotfix"
13        default:
14            return "${baseUrl}/maven-experimental"
15    }
16}
17
18pipeline {
19    agent any
20
21    environment {
22        CLOUDREPO_URL = getCloudRepoUrl(env.BRANCH_NAME, 'your-org')
23    }
24
25    stages {
26        stage('Deploy') {
27            steps {
28                echo "Deploying to: ${CLOUDREPO_URL}"
29                // ... deployment steps
30            }
31        }
32    }
33}

Advanced Topics

Parallel Builds

Execute builds in parallel for multiple modules or platforms:

Parallel Build Pipeline
  1pipeline {
  2    agent none
  3
  4    stages {
  5        stage('Build All') {
  6            parallel {
  7                stage('Build Java 8') {
  8                    agent any
  9                    tools {
 10                        jdk 'JDK-8'
 11                        maven 'Maven-3.9.5'
 12                    }
 13                    steps {
 14                        withCredentials([usernamePassword(
 15                            credentialsId: 'cloudrepo-credentials',
 16                            usernameVariable: 'CLOUDREPO_USERNAME',
 17                            passwordVariable: 'CLOUDREPO_PASSWORD'
 18                        )]) {
 19                            sh 'mvn clean package -Djava.version=8'
 20                        }
 21                    }
 22                    post {
 23                        success {
 24                            archiveArtifacts 'target/*.jar'
 25                        }
 26                    }
 27                }
 28
 29                stage('Build Java 11') {
 30                    agent any
 31                    tools {
 32                        jdk 'JDK-11'
 33                        maven 'Maven-3.9.5'
 34                    }
 35                    steps {
 36                        withCredentials([usernamePassword(
 37                            credentialsId: 'cloudrepo-credentials',
 38                            usernameVariable: 'CLOUDREPO_USERNAME',
 39                            passwordVariable: 'CLOUDREPO_PASSWORD'
 40                        )]) {
 41                            sh 'mvn clean package -Djava.version=11'
 42                        }
 43                    }
 44                    post {
 45                        success {
 46                            archiveArtifacts 'target/*.jar'
 47                        }
 48                    }
 49                }
 50
 51                stage('Build Java 17') {
 52                    agent any
 53                    tools {
 54                        jdk 'JDK-17'
 55                        maven 'Maven-3.9.5'
 56                    }
 57                    steps {
 58                        withCredentials([usernamePassword(
 59                            credentialsId: 'cloudrepo-credentials',
 60                            usernameVariable: 'CLOUDREPO_USERNAME',
 61                            passwordVariable: 'CLOUDREPO_PASSWORD'
 62                        )]) {
 63                            sh 'mvn clean package -Djava.version=17'
 64                        }
 65                    }
 66                    post {
 67                        success {
 68                            archiveArtifacts 'target/*.jar'
 69                        }
 70                    }
 71                }
 72            }
 73        }
 74
 75        stage('Deploy All') {
 76            agent any
 77            when {
 78                branch 'main'
 79            }
 80            steps {
 81                withCredentials([usernamePassword(
 82                    credentialsId: 'cloudrepo-credentials',
 83                    usernameVariable: 'CLOUDREPO_USERNAME',
 84                    passwordVariable: 'CLOUDREPO_PASSWORD'
 85                )]) {
 86                    sh '''
 87                        # Deploy all built artifacts
 88                        for jar in target/*.jar; do
 89                            mvn deploy:deploy-file \
 90                                -Dfile=$jar \
 91                                -DrepositoryId=cloudrepo \
 92                                -Durl=https://your-org.mycloudrepo.io/repositories/maven-releases \
 93                                -DgroupId=com.example \
 94                                -DartifactId=multi-jdk-artifact \
 95                                -Dversion=1.0.0 \
 96                                -Dpackaging=jar \
 97                                -Dclassifier=$(basename $jar .jar)
 98                        done
 99                    '''
100                }
101            }
102        }
103    }
104}

Matrix Builds

Build and test across multiple configurations:

Matrix Build Configuration
 1pipeline {
 2    agent none
 3
 4    stages {
 5        stage('Matrix Build') {
 6            matrix {
 7                agent any
 8                axes {
 9                    axis {
10                        name 'JAVA_VERSION'
11                        values '8', '11', '17', '21'
12                    }
13                    axis {
14                        name 'OS'
15                        values 'linux', 'windows', 'macos'
16                    }
17                }
18                excludes {
19                    exclude {
20                        axis {
21                            name 'JAVA_VERSION'
22                            values '8'
23                        }
24                        axis {
25                            name 'OS'
26                            values 'macos'
27                        }
28                    }
29                }
30                stages {
31                    stage('Build') {
32                        steps {
33                            script {
34                                def jdkTool = "JDK-${JAVA_VERSION}"
35                                tools {
36                                    jdk jdkTool
37                                }
38                            }
39                            withCredentials([usernamePassword(
40                                credentialsId: 'cloudrepo-credentials',
41                                usernameVariable: 'CLOUDREPO_USERNAME',
42                                passwordVariable: 'CLOUDREPO_PASSWORD'
43                            )]) {
44                                sh """
45                                    echo "Building on ${OS} with Java ${JAVA_VERSION}"
46                                    mvn clean package \
47                                        -Djava.version=${JAVA_VERSION} \
48                                        -Dos.name=${OS}
49                                """
50                            }
51                        }
52                    }
53                    stage('Test') {
54                        steps {
55                            sh 'mvn test'
56                        }
57                    }
58                    stage('Deploy') {
59                        when {
60                            allOf {
61                                branch 'main'
62                                expression { JAVA_VERSION == '17' }
63                                expression { OS == 'linux' }
64                            }
65                        }
66                        steps {
67                            withCredentials([usernamePassword(
68                                credentialsId: 'cloudrepo-credentials',
69                                usernameVariable: 'CLOUDREPO_USERNAME',
70                                passwordVariable: 'CLOUDREPO_PASSWORD'
71                            )]) {
72                                sh 'mvn deploy'
73                            }
74                        }
75                    }
76                }
77            }
78        }
79    }
80}

Docker Integration

Build and publish Docker images with artifacts from CloudRepo:

Docker Build with CloudRepo Artifacts
 1pipeline {
 2    agent any
 3
 4    environment {
 5        DOCKER_REGISTRY = 'docker.io'
 6        DOCKER_IMAGE = 'myorg/myapp'
 7        CLOUDREPO_ORG = 'your-org'
 8    }
 9
10    stages {
11        stage('Build Application') {
12            steps {
13                withCredentials([usernamePassword(
14                    credentialsId: 'cloudrepo-credentials',
15                    usernameVariable: 'CLOUDREPO_USERNAME',
16                    passwordVariable: 'CLOUDREPO_PASSWORD'
17                )]) {
18                    sh 'mvn clean package'
19                }
20            }
21        }
22
23        stage('Build Docker Image') {
24            steps {
25                script {
26                    // Create Dockerfile that downloads artifacts from CloudRepo
27                    writeFile file: 'Dockerfile', text: '''
28                        FROM openjdk:17-slim
29
30                        ARG CLOUDREPO_USERNAME
31                        ARG CLOUDREPO_PASSWORD
32                        ARG VERSION
33
34                        RUN apt-get update && apt-get install -y curl
35
36                        # Download artifact from CloudRepo
37                        RUN curl -u ${CLOUDREPO_USERNAME}:${CLOUDREPO_PASSWORD} \
38                            -o app.jar \
39                            "https://your-org.mycloudrepo.io/repositories/maven-releases/com/example/myapp/${VERSION}/myapp-${VERSION}.jar"
40
41                        EXPOSE 8080
42                        ENTRYPOINT ["java", "-jar", "/app.jar"]
43                    '''
44
45                    withCredentials([usernamePassword(
46                        credentialsId: 'cloudrepo-credentials',
47                        usernameVariable: 'CLOUDREPO_USERNAME',
48                        passwordVariable: 'CLOUDREPO_PASSWORD'
49                    )]) {
50                        def image = docker.build("${DOCKER_IMAGE}:${BUILD_NUMBER}",
51                            "--build-arg CLOUDREPO_USERNAME=${CLOUDREPO_USERNAME} " +
52                            "--build-arg CLOUDREPO_PASSWORD=${CLOUDREPO_PASSWORD} " +
53                            "--build-arg VERSION=1.0.0 .")
54
55                        docker.withRegistry("https://${DOCKER_REGISTRY}", 'docker-credentials') {
56                            image.push()
57                            image.push('latest')
58                        }
59                    }
60                }
61            }
62        }
63    }
64}

Artifact Promotion

Promote artifacts between repositories (e.g., from staging to production):

Artifact Promotion Pipeline
  1pipeline {
  2    agent any
  3
  4    parameters {
  5        string(name: 'GROUP_ID', defaultValue: 'com.example', description: 'Group ID')
  6        string(name: 'ARTIFACT_ID', description: 'Artifact ID')
  7        string(name: 'VERSION', description: 'Version to promote')
  8        choice(name: 'SOURCE_REPO', choices: ['staging', 'qa', 'dev'], description: 'Source repository')
  9        choice(name: 'TARGET_REPO', choices: ['production', 'staging', 'qa'], description: 'Target repository')
 10    }
 11
 12    environment {
 13        CLOUDREPO_ORG = 'your-org'
 14    }
 15
 16    stages {
 17        stage('Validate Parameters') {
 18            steps {
 19                script {
 20                    if (!params.ARTIFACT_ID || !params.VERSION) {
 21                        error("Artifact ID and Version are required")
 22                    }
 23                    if (params.SOURCE_REPO == params.TARGET_REPO) {
 24                        error("Source and target repositories must be different")
 25                    }
 26                }
 27            }
 28        }
 29
 30        stage('Download Artifact') {
 31            steps {
 32                withCredentials([usernamePassword(
 33                    credentialsId: 'cloudrepo-credentials',
 34                    usernameVariable: 'CLOUDREPO_USERNAME',
 35                    passwordVariable: 'CLOUDREPO_PASSWORD'
 36                )]) {
 37                    sh """
 38                        # Download artifact from source repository
 39                        curl -u ${CLOUDREPO_USERNAME}:${CLOUDREPO_PASSWORD} \
 40                            -o ${params.ARTIFACT_ID}-${params.VERSION}.jar \
 41                            "https://${CLOUDREPO_ORG}.mycloudrepo.io/repositories/${params.SOURCE_REPO}/${params.GROUP_ID.replace('.', '/')}/${params.ARTIFACT_ID}/${params.VERSION}/${params.ARTIFACT_ID}-${params.VERSION}.jar"
 42
 43                        # Download POM
 44                        curl -u ${CLOUDREPO_USERNAME}:${CLOUDREPO_PASSWORD} \
 45                            -o ${params.ARTIFACT_ID}-${params.VERSION}.pom \
 46                            "https://${CLOUDREPO_ORG}.mycloudrepo.io/repositories/${params.SOURCE_REPO}/${params.GROUP_ID.replace('.', '/')}/${params.ARTIFACT_ID}/${params.VERSION}/${params.ARTIFACT_ID}-${params.VERSION}.pom"
 47
 48                        # Verify download
 49                        ls -la ${params.ARTIFACT_ID}-${params.VERSION}.*
 50                    """
 51                }
 52            }
 53        }
 54
 55        stage('Verify Artifact') {
 56            steps {
 57                sh """
 58                    # Check JAR integrity
 59                    jar tf ${params.ARTIFACT_ID}-${params.VERSION}.jar > /dev/null
 60                    echo "JAR file is valid"
 61
 62                    # Optional: Run security scan
 63                    # dependency-check --scan ${params.ARTIFACT_ID}-${params.VERSION}.jar
 64                """
 65            }
 66        }
 67
 68        stage('Promote to Target') {
 69            steps {
 70                input message: "Promote ${params.ARTIFACT_ID}:${params.VERSION} to ${params.TARGET_REPO}?",
 71                      ok: 'Promote'
 72
 73                withCredentials([usernamePassword(
 74                    credentialsId: 'cloudrepo-credentials',
 75                    usernameVariable: 'CLOUDREPO_USERNAME',
 76                    passwordVariable: 'CLOUDREPO_PASSWORD'
 77                )]) {
 78                    sh """
 79                        # Upload to target repository
 80                        mvn deploy:deploy-file \
 81                            -Dfile=${params.ARTIFACT_ID}-${params.VERSION}.jar \
 82                            -DpomFile=${params.ARTIFACT_ID}-${params.VERSION}.pom \
 83                            -DrepositoryId=cloudrepo-${params.TARGET_REPO} \
 84                            -Durl=https://${CLOUDREPO_ORG}.mycloudrepo.io/repositories/${params.TARGET_REPO} \
 85                            -DgroupId=${params.GROUP_ID} \
 86                            -DartifactId=${params.ARTIFACT_ID} \
 87                            -Dversion=${params.VERSION} \
 88                            -Dpackaging=jar
 89                    """
 90                }
 91            }
 92        }
 93
 94        stage('Tag Promotion') {
 95            steps {
 96                script {
 97                    def timestamp = new Date().format('yyyy-MM-dd_HH-mm-ss')
 98                    def promotionTag = "promoted-${params.TARGET_REPO}-${params.VERSION}-${timestamp}"
 99
100                    sshagent(credentials: ['git-ssh-key']) {
101                        sh """
102                            git tag -a ${promotionTag} -m "Promoted ${params.ARTIFACT_ID}:${params.VERSION} to ${params.TARGET_REPO}"
103                            git push origin ${promotionTag}
104                        """
105                    }
106                }
107            }
108        }
109    }
110
111    post {
112        success {
113            emailext(
114                subject: "Artifact Promoted: ${params.ARTIFACT_ID}:${params.VERSION}",
115                body: """
116                    Artifact successfully promoted:
117                    - Artifact: ${params.GROUP_ID}:${params.ARTIFACT_ID}:${params.VERSION}
118                    - From: ${params.SOURCE_REPO}
119                    - To: ${params.TARGET_REPO}
120                    - Build: ${BUILD_URL}
121                """,
122                to: 'release-team@example.com'
123            )
124        }
125    }
126}

Build Artifacts Retention

Configure retention policies for build artifacts:

Artifact Retention Configuration
 1pipeline {
 2    agent any
 3
 4    options {
 5        // Keep only last 10 builds
 6        buildDiscarder(logRotator(
 7            numToKeepStr: '10',
 8            artifactNumToKeepStr: '5',
 9            daysToKeepStr: '30',
10            artifactDaysToKeepStr: '15'
11        ))
12
13        // Timeout for the entire pipeline
14        timeout(time: 1, unit: 'HOURS')
15
16        // Skip default checkout
17        skipDefaultCheckout()
18
19        // Timestamps in console output
20        timestamps()
21    }
22
23    stages {
24        stage('Cleanup Old Artifacts') {
25            steps {
26                script {
27                    // Clean CloudRepo artifacts older than 90 days
28                    withCredentials([usernamePassword(
29                        credentialsId: 'cloudrepo-credentials',
30                        usernameVariable: 'CLOUDREPO_USERNAME',
31                        passwordVariable: 'CLOUDREPO_PASSWORD'
32                    )]) {
33                        sh '''
34                            # This is a placeholder - CloudRepo API endpoint for cleanup
35                            # would go here when available
36                            echo "Cleanup would happen here"
37                        '''
38                    }
39                }
40            }
41        }
42
43        stage('Build and Archive') {
44            steps {
45                checkout scm
46                sh 'mvn clean package'
47
48                archiveArtifacts artifacts: 'target/*.jar',
49                                fingerprint: true,
50                                onlyIfSuccessful: true
51            }
52        }
53    }
54}

Security Best Practices

Credential Isolation

Implement proper credential isolation using Jenkins folders and RBAC:

Folder-Level Credentials:

  1. Create a folder for each team/project

  2. Add credentials at the folder level

  3. Configure folder permissions

Folder-Level Credential Usage
 1// Job DSL for creating folder with credentials
 2folder('team-a') {
 3    description('Team A Projects')
 4
 5    properties {
 6        folderCredentialsProperty {
 7            domainCredentials {
 8                domainCredentials {
 9                    domain {
10                        name('CloudRepo')
11                        description('CloudRepo Credentials for Team A')
12                    }
13                    credentials {
14                        usernamePassword {
15                            scope('GLOBAL')
16                            id('team-a-cloudrepo')
17                            description('Team A CloudRepo Credentials')
18                            username('team-a-user')
19                            password('${TEAM_A_PASSWORD}')
20                        }
21                    }
22                }
23            }
24        }
25    }
26}

Repository Permissions

Configure appropriate permissions in CloudRepo:

Note

CloudRepo supports fine-grained permissions per repository:

  • Read: Download/consume artifacts

  • Write: Upload/publish artifacts

  • Admin: Manage repository settings

  • Delete: Remove artifacts (use with caution)

Best Practices:

  1. Use separate credentials for different environments

  2. Implement least-privilege principle

  3. Regular credential rotation

  4. Audit access logs

Network Security

Configure Jenkins for secure CloudRepo communication:

Network Security Configuration
 1pipeline {
 2    agent any
 3
 4    environment {
 5        // Use HTTPS only
 6        CLOUDREPO_URL = 'https://your-org.mycloudrepo.io/repositories/maven-releases'
 7
 8        // Proxy configuration if needed
 9        HTTPS_PROXY = 'http://proxy.company.com:8080'
10        NO_PROXY = 'localhost,127.0.0.1,.company.com'
11    }
12
13    stages {
14        stage('Secure Deploy') {
15            steps {
16                withCredentials([usernamePassword(
17                    credentialsId: 'cloudrepo-credentials',
18                    usernameVariable: 'CLOUDREPO_USERNAME',
19                    passwordVariable: 'CLOUDREPO_PASSWORD'
20                )]) {
21                    sh '''
22                        # Configure Maven to use HTTPS only
23                        mvn deploy \
24                            -Dmaven.wagon.http.ssl.insecure=false \
25                            -Dmaven.wagon.http.ssl.allowall=false \
26                            -Dmaven.wagon.http.ssl.ignore.validity.dates=false
27                    '''
28                }
29            }
30        }
31    }
32}

Audit Logging

Implement comprehensive audit logging:

Audit Logging Pipeline
 1@Library('shared-library') _
 2
 3pipeline {
 4    agent any
 5
 6    stages {
 7        stage('Audit Deploy') {
 8            steps {
 9                script {
10                    def auditLog = [:]
11                    auditLog.timestamp = new Date().format('yyyy-MM-dd HH:mm:ss')
12                    auditLog.user = currentBuild.getBuildCauses()[0].userId
13                    auditLog.job = env.JOB_NAME
14                    auditLog.build = env.BUILD_NUMBER
15
16                    withCredentials([usernamePassword(
17                        credentialsId: 'cloudrepo-credentials',
18                        usernameVariable: 'CLOUDREPO_USERNAME',
19                        passwordVariable: 'CLOUDREPO_PASSWORD'
20                    )]) {
21                        auditLog.repository = 'CloudRepo'
22                        auditLog.action = 'DEPLOY'
23
24                        try {
25                            sh 'mvn deploy'
26                            auditLog.status = 'SUCCESS'
27                        } catch (Exception e) {
28                            auditLog.status = 'FAILED'
29                            auditLog.error = e.getMessage()
30                            throw e
31                        } finally {
32                            // Log to external system
33                            writeJSON file: "audit-${BUILD_NUMBER}.json", json: auditLog
34                            archiveArtifacts artifacts: "audit-${BUILD_NUMBER}.json"
35
36                            // Send to SIEM/logging system
37                            sh """
38                                curl -X POST https://logging.company.com/api/audit \
39                                    -H "Content-Type: application/json" \
40                                    -d @audit-${BUILD_NUMBER}.json
41                            """
42                        }
43                    }
44                }
45            }
46        }
47    }
48}

Troubleshooting

Common Authentication Issues

Issue: 401 Unauthorized Error

Symptoms:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:3.0.0:deploy
(default-deploy) on project my-app: Failed to deploy artifacts:
Could not transfer artifact: Unauthorized (401)

Solutions:

  1. Verify credentials are correct:

    stage('Test Credentials') {
        steps {
            withCredentials([usernamePassword(
                credentialsId: 'cloudrepo-credentials',
                usernameVariable: 'USER',
                passwordVariable: 'PASS'
            )]) {
                sh '''
                    # Test authentication
                    curl -I -u ${USER}:${PASS} \
                        https://your-org.mycloudrepo.io/repositories/maven-releases/
                '''
            }
        }
    }
    
  2. Check repository permissions in CloudRepo dashboard

  3. Ensure credentials ID matches in Jenkins configuration

  4. Verify environment variable names match in settings.xml

Issue: 403 Forbidden Error

Symptoms:

[ERROR] Failed to deploy artifacts: Could not transfer artifact: Forbidden (403)

Solutions:

  1. User lacks write permissions for the repository

  2. Repository type mismatch (e.g., deploying SNAPSHOT to release repo)

  3. Artifact already exists (for release repositories)

Network Connectivity Problems

Issue: Connection Timeout

Symptoms:

[ERROR] Failed to transfer file: Connect to your-org.mycloudrepo.io:443 timed out

Diagnostic Steps:

Network Diagnostics Pipeline
 1pipeline {
 2    agent any
 3
 4    stages {
 5        stage('Network Diagnostics') {
 6            steps {
 7                sh '''
 8                    # Test DNS resolution
 9                    nslookup your-org.mycloudrepo.io
10
11                    # Test connectivity
12                    curl -v https://your-org.mycloudrepo.io/health
13
14                    # Test with proxy if configured
15                    if [ ! -z "$HTTPS_PROXY" ]; then
16                        curl -v --proxy $HTTPS_PROXY https://your-org.mycloudrepo.io/health
17                    fi
18
19                    # Check MTU issues
20                    ping -c 4 -M do -s 1472 your-org.mycloudrepo.io || true
21                '''
22            }
23        }
24    }
25}

Issue: SSL Certificate Problems

Symptoms:

PKIX path building failed: unable to find valid certification path

Solutions:

  1. Import CloudRepo certificate to Java truststore:

    keytool -import -trustcacerts -keystore $JAVA_HOME/lib/security/cacerts \
            -storepass changeit -alias cloudrepo \
            -file cloudrepo-cert.pem
    
  2. Or configure Maven to use custom truststore:

    mvn deploy -Djavax.net.ssl.trustStore=/path/to/truststore \
               -Djavax.net.ssl.trustStorePassword=password
    

Plugin Conflicts

Issue: Conflicting Plugin Versions

Symptoms:

java.lang.NoSuchMethodError: No such DSL method 'withCredentials'

Solutions:

  1. Update all plugins to compatible versions:

    // Check plugin versions
    jenkins.model.Jenkins.instance.pluginManager.plugins.each {
        println "${it.getShortName()}: ${it.getVersion()}"
    }
    
  2. Use Plugin Management in Jenkinsfile:

    @Library('pipeline-library@2.0') _
    
    pipeline {
        agent any
    
        options {
            skipDefaultCheckout()
            buildDiscarder(logRotator(numToKeepStr: '10'))
        }
        // ...
    }
    

Build Performance Optimization

Optimize Maven Builds:

Performance Optimized Pipeline
 1pipeline {
 2    agent any
 3
 4    environment {
 5        MAVEN_OPTS = '-Xmx2048m -XX:MaxPermSize=512m -Dmaven.artifact.threads=10'
 6    }
 7
 8    stages {
 9        stage('Parallel Modules Build') {
10            steps {
11                sh '''
12                    # Build in parallel
13                    mvn clean install -T 2C
14
15                    # Skip unnecessary operations
16                    mvn deploy -DskipTests -Dmaven.javadoc.skip=true \
17                               -Dmaven.source.skip=true -Dcheckstyle.skip=true
18                '''
19            }
20        }
21
22        stage('Cache Dependencies') {
23            steps {
24                // Use Jenkins workspace cache
25                cache(maxCacheSize: 500, caches: [
26                    arbitraryFileCache(
27                        path: '.m2/repository',
28                        fingerprinting: true
29                    )
30                ]) {
31                    sh 'mvn dependency:go-offline'
32                }
33            }
34        }
35    }
36}

Optimize Gradle Builds:

pipeline {
    agent any

    environment {
        GRADLE_OPTS = '-Xmx2048m -Dorg.gradle.daemon=true -Dorg.gradle.parallel=true'
    }

    stages {
        stage('Gradle Build with Cache') {
            steps {
                sh '''
                    # Enable build cache
                    ./gradlew build --build-cache --parallel \
                                    --max-workers=4 \
                                    --configure-on-demand
                '''
            }
        }
    }
}

Additional Resources

Jenkins Documentation

CloudRepo Resources

Support

Note

CloudRepo includes professional support with all plans. If you encounter any issues with Jenkins integration:

Example Repositories

Complete working examples are available on GitHub:

See also