CI/CD

Jenkins CI for TTCN-3 conformance testing

Declarative Jenkins pipeline for 3GPP TTCN-3 campaigns: credentials binding, parallel lane stages, JUnit publishing, and archived evidence.

7 min read

Jenkins remains the default in telecom engineering organisations, and it maps cleanly onto AEON: the pipeline never touches hardware, so agents stay stateless and disposable.

Declarative pipeline

Jenkinsfilegroovy
pipeline {
  agent { docker { image 'ghcr.io/aeon-cloud/cli:1.12.3' } }
  environment { AEON_PROJECT = 'nr-modem-x75' }

  stages {
    stage('Push build') {
      steps {
        withCredentials([string(credentialsId: 'aeon-token', variable: 'AEON_TOKEN')]) {
          sh 'aeon builds push ./dist/ue.tar.gz --tag "${GIT_COMMIT}" --commit "${GIT_COMMIT}"'
        }
      }
    }

    stage('Conformance') {
      parallel {
        stage('NAS')  { steps { runCampaign('nas')  } }
        stage('RRC')  { steps { runCampaign('rrc')  } }
        stage('PDCP') { steps { runCampaign('pdcp') } }
      }
    }
  }

  post {
    always {
      junit 'reports/**/junit-*.xml'
      archiveArtifacts artifacts: 'evidence/**', allowEmptyArchive: true
    }
  }
}

def runCampaign(String name) {
  withCredentials([string(credentialsId: 'aeon-token', variable: 'AEON_TOKEN')]) {
    sh """
      aeon exec run --campaign ${name} --build "${GIT_COMMIT}" --wait --exit-code --quiet
      aeon reports get --build "${GIT_COMMIT}" --campaign ${name} \
        --format junit --output reports/junit-${name}.xml
    """
  }
}

Why parallel stages are safe

Each campaign reserves its own lane, so parallel Jenkins stages do not contend for a shared physical tester. This is the single largest workflow change versus a racked box: concurrency is a quota question, not a scheduling conflict between teams.

Run this against a real SDR lane

The tester is a service, not a box. Push a build, reserve a lane, get a verdict.