Add Jenkinsfile for CI integration.
diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644
index 0000000..a0fe701
--- /dev/null
+++ b/Jenkinsfile
@@ -0,0 +1,239 @@
+@Library("cmsis")
+
+DOCKERINFO = [
+ 'linux_staging': [
+ 'registryUrl': 'mcu--docker-staging.eu-west-1.artifactory.aws.arm.com',
+ 'registryCredentialsId': 'artifactory',
+ 'k8sPullSecret': 'artifactory-mcu-docker-staging',
+ 'namespace': 'mcu--docker-staging',
+ 'image': 'cmsis_fusa/linux',
+ 'label': "${JENKINS_ENV}-${JOB_BASE_NAME}-${BUILD_NUMBER}"
+ ],
+ 'linux_production': [
+ 'registryUrl': 'mcu--docker.eu-west-1.artifactory.aws.arm.com',
+ 'registryCredentialsId': 'artifactory',
+ 'namespace': 'mcu--docker',
+ 'k8sPullSecret': 'artifactory-mcu-docker',
+ 'image': 'cmsis_fusa/linux',
+ 'label': 'aws'
+ ],
+ 'windows_staging': [
+ 'registryUrl': 'mcu--docker-staging.eu-west-1.artifactory.aws.arm.com',
+ 'registryCredentialsId': 'artifactory',
+ 'namespace': 'mcu--docker-staging',
+ 'image': 'cmsis_fusa/windows',
+ 'label': "${JENKINS_ENV}-${JOB_BASE_NAME}-${BUILD_NUMBER}"
+ ],
+ 'windows_production': [
+ 'registryUrl': 'mcu--docker.eu-west-1.artifactory.aws.arm.com',
+ 'registryCredentialsId': 'artifactory',
+ 'namespace': 'mcu--docker',
+ 'image': 'cmsis_fusa/windows',
+ 'label': 'aws'
+ ]
+]
+
+dockerinfo_linux = DOCKERINFO['linux_production']
+dockerinfo_windows = DOCKERINFO['windows_production']
+
+isPrecommit = (JOB_BASE_NAME == 'pre_commit')
+isNightly = (JOB_BASE_NAME == 'nightly')
+
+patternCoreM = [
+ '^CMSIS/Core/Include/.*',
+ '^Device/ARM/ARMCM.*'
+]
+
+patternCoreA = [
+ '^CMSIS/Core_A/Include/.*',
+ '^Device/ARM/ARMCA.*'
+]
+
+patternCoreValidation = [
+ '^CMSIS/CoreValidation/.*'
+]
+
+CONFIGURATIONS = [
+ 'pre_commit': [
+ 'mdevices': ['CM0', 'CM3', 'CM4FP', 'CM7DP', 'CM23', 'CM33NS', 'CM35PS'],
+ 'adevices': ['CA7', 'CA9neon'],
+ 'devices' : [],
+ 'configs' : [
+ 'AC6': ['low', 'tiny'],
+ 'AC6LTM': ['low', 'tiny']
+ ]
+ ],
+ 'nightly':[
+ 'devices' : ['CM0', 'CM0plus', 'CM3', 'CM4', 'CM4FP', 'CM7', 'CM7SP', 'CM7DP',
+ 'CM23', 'CM23S', 'CM23NS', 'CM33', 'CM33S', 'CM33NS',
+ 'CM35P', 'CM35PS', 'CM35PNS',
+ 'CA5', 'CA5neon', 'CA7', 'CA7neon', 'CA9', 'CA9neon'],
+ 'configs' : [
+ 'AC6': ['low', 'mid', 'high', 'size', 'tiny'],
+ 'AC6LTM': ['low', 'mid', 'high', 'size', 'tiny']
+ ]
+ ]
+]
+CONFIGURATION = CONFIGURATIONS[JOB_BASE_NAME]
+
+// ---- PIPELINE CODE ----
+
+def getChangeset() {
+ def fileset = sh encoding: 'UTF-8', label: '', returnStdout: true, script: 'git diff --name-only HEAD~1..HEAD'
+ return fileset.split('\n')
+}
+
+def fileSetMatches(fileset, patternset) {
+ return patternset.any { p ->
+ fileset.any{ f -> f ==~ p }
+ }
+}
+
+FORCE_BUILD = false
+CORE_VALIDATION = true
+COMMIT = null
+VERSION = null
+
+pipeline {
+ options {
+ timestamps()
+ timeout(time: 1, unit: 'HOURS')
+ ansiColor('xterm')
+ skipDefaultCheckout()
+ }
+ agent { label 'master' }
+ stages {
+ stage('Checkout') {
+ steps {
+ script {
+ COMMIT = checkoutScmWithRetry(3)
+ echo "COMMIT: ${COMMIT}"
+ VERSION = (sh(returnStdout: true, script: 'git describe --always')).trim()
+ echo "VERSION: '${VERSION}'"
+ }
+ }
+ }
+
+ stage('Analyse') {
+ when {
+ expression { return isPrecommit }
+ beforeOptions true
+ }
+ steps {
+ script {
+ def fileset = changeset
+ def hasCoreM = fileSetMatches(fileset, patternCoreM)
+ def hasCoreA = fileSetMatches(fileset, patternCoreA)
+ def hasCoreValidation = fileSetMatches(fileset, patternCoreValidation)
+
+echo """Change analysis:
+- hasCoreM = ${hasCoreM}
+- hasCoreA = ${hasCoreA}
+- hasCoreValidation = ${hasCoreValidation}
+"""
+
+ if (hasCoreM || hasCoreValidation) {
+ CONFIGURATION['devices'] += CONFIGURATION['mdevices']
+ }
+ if (hasCoreA || hasCoreValidation) {
+ CONFIGURATION['devices'] += CONFIGURATION['adevices']
+ }
+
+ CORE_VALIDATION &= hasCoreM || hasCoreA || hasCoreValidation
+
+echo """Stage schedule:
+- CORE_VALIDATION = ${CORE_VALIDATION}
+"""
+ }
+ }
+ }
+
+ stage('CoreValidation') {
+ when {
+ expression { return CORE_VALIDATION }
+ beforeOptions true
+ }
+ matrix {
+ axes {
+ axis {
+ name 'DEVICE'
+ values 'CM0', 'CM0plus', 'CM3', 'CM4', 'CM4FP', 'CM7', 'CM7SP', 'CM7DP',
+ 'CM23', 'CM23S', 'CM23NS', 'CM33', 'CM33S', 'CM33NS',
+ 'CM35P', 'CM35PS', 'CM35PNS',
+ 'CA5', 'CA5neon', 'CA7', 'CA7neon', 'CA9', 'CA9neon'
+ }
+ }
+ stages {
+ stage('Test') {
+ when {
+ expression { return DEVICE in CONFIGURATION['devices'] }
+ beforeOptions true
+ }
+ agent {
+ kubernetes {
+ defaultContainer 'cmsis'
+ slaveConnectTimeout 600
+ yaml """\
+ apiVersion: v1
+ kind: Pod
+ spec:
+ imagePullSecrets:
+ - name: ${dockerinfo_linux['k8sPullSecret']}
+ securityContext:
+ runAsUser: 1000
+ runAsGroup: 1000
+ containers:
+ - name: cmsis
+ image: ${dockerinfo_linux['registryUrl']}/${dockerinfo_linux['image']}:${dockerinfo_linux['label']}
+ alwaysPullImage: true
+ imagePullPolicy: Always
+ command:
+ - sleep
+ args:
+ - infinity
+ resources:
+ requests:
+ cpu: 2
+ memory: 2Gi
+ """.stripIndent()
+ }
+ }
+ steps {
+ checkoutScmWithRetry(3)
+ dir('CMSIS/CoreValidation/Tests') {
+ script {
+ CONFIGURATION['configs'].each { COMPILER, OPTS ->
+ tee("CV_${COMPILER}_${DEVICE}.log") {
+ sh "python3 build.py -d ${DEVICE} -c ${COMPILER} -o ${OPTS.join(' -o ')} build run"
+ }
+ }
+ }
+
+ archiveArtifacts artifacts: "CoreValidation_*.zip", allowEmptyArchive: true
+ stash name: "CV_${DEVICE}", includes: '*.log, *.junit'
+ }
+ }
+ }
+ }
+ }
+ }
+
+ stage('Results') {
+ steps {
+ dir('results') {
+ deleteDir()
+ script {
+ CONFIGURATION['devices'].each { unstash "CV_${it}" }
+ }
+
+ recordIssues tools: [clang(id: 'AC6', name: 'Arm Compiler 6', pattern: 'CV_AC6_*.log')]
+ recordIssues tools: [clang(id: 'AC6LTM', name: 'Arm Compiler 6 LTM', pattern: 'CV_AC6LTM_*.log')]
+ xunit([
+ JUnit(pattern: 'corevalidation_*.junit', failIfNotNew: false, skipNoTestFiles: true)
+ ])
+ }
+
+ }
+ }
+ }
+}