From fa36dfa74fa8c08067a375175f9d5ee47892d38f Mon Sep 17 00:00:00 2001 From: Boris Shestov Date: Mon, 18 Dec 2023 17:01:12 +0300 Subject: [PATCH] DO-130/pipeline_doxygen (#5) [DO-130] Reviewed-on: https://git.avroid.tech/DevOps/jenkins-pipelines/pulls/5 --- .gitignore | 12 ++ jobs-dsl/folders/Docs.groovy | 8 + jobs-dsl/jobs/Docs/Eisen/doxygen.groovy | 29 ++++ pipelines/Docs/Eisen/doxygen.groovy | 196 ++++++++++++++++++++++++ pipelines/jobs-dsl/jobs-dsl.groovy | 40 ++--- 5 files changed, 265 insertions(+), 20 deletions(-) create mode 100644 .gitignore create mode 100644 jobs-dsl/folders/Docs.groovy create mode 100644 jobs-dsl/jobs/Docs/Eisen/doxygen.groovy create mode 100644 pipelines/Docs/Eisen/doxygen.groovy diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..56b371c --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +.idea +.vault_password_file +.vscode +.vagrant +.venv +venv +__pycache__ +*~ +**/.DS_Store +ansible_collections +*.log +._* diff --git a/jobs-dsl/folders/Docs.groovy b/jobs-dsl/folders/Docs.groovy new file mode 100644 index 0000000..dff8e95 --- /dev/null +++ b/jobs-dsl/folders/Docs.groovy @@ -0,0 +1,8 @@ +folder('Docs') { + displayName('Docs') + description('Docs') +} + +folder('Docs/Eisen') { + description('Generate doxygen documentation for Eisen team') +} diff --git a/jobs-dsl/jobs/Docs/Eisen/doxygen.groovy b/jobs-dsl/jobs/Docs/Eisen/doxygen.groovy new file mode 100644 index 0000000..b0f54d4 --- /dev/null +++ b/jobs-dsl/jobs/Docs/Eisen/doxygen.groovy @@ -0,0 +1,29 @@ +pipelineJob('Docs/Eisen/doxygen') { + definition { + cpsScm { + scm { + git { + remote { + url("${JENKINS_GIT_REPOSITORY_URL}/DevOps/jenkins-pipelines.git") + credentials("${JENKINS_GIT_CREDENTIALS_HTTP}") + } + branch('master') + } + } + scriptPath('pipelines/Docs/Eisen/doxygen.groovy') + } + } + + properties { + disableConcurrentBuilds() + } + + parameters { + string { name('BRANCH') + defaultValue('master') + } + booleanParam { name('onlyUpdatePipeline') + defaultValue(false) + } + } +} diff --git a/pipelines/Docs/Eisen/doxygen.groovy b/pipelines/Docs/Eisen/doxygen.groovy new file mode 100644 index 0000000..b7e3f9d --- /dev/null +++ b/pipelines/Docs/Eisen/doxygen.groovy @@ -0,0 +1,196 @@ +@Library('shared-lib') _ + +import tech.avroid.scm.Git + +properties([ + buildDiscarder(logRotator(numToKeepStr: '100')), + disableConcurrentBuilds(), + parameters([ + string (name: "BRANCH", defaultValue: "master", + description: "OS repo branch name."), + booleanParam (name: "onlyUpdatePipeline", defaultValue: false, + description: "Only update pipeline and exit.") + ]), + pipelineTriggers( + [GenericTrigger( + causeString: 'Generic Cause', + allowSeveralTriggersPerBuild: false, + genericVariables: [[defaultValue: '', key: 'webhookBody', value: '$']], + token: env.JOB_NAME) + ] + ) +]) + +String projectName = 'OS' +String owner = 'Eisen' +String gitRepoName = "${owner}/${projectName}" +String nexusRepoName = "eisen-os_doc-feature" +Git git = new Git(this, env.JENKINS_GIT_CREDENTIALS_SSH) +String doxygenImage = "${env.JENKINS_DOCKER_REGISTRY}/devops/doxygen:1.9.8" + +podTemplate(workspaceVolume: hostPathWorkspaceVolume(hostPath: "/data"), + yaml: ''' + apiVersion: v1 + kind: Pod + spec: + containers: + - name: doxygen + image: harbor.avroid.tech/devops/doxygen:1.9.8 + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + command: ["/bin/bash"] + tty: true + resources: + limits: + cpu: 300m + memory: 256Mi + requests: + cpu: 300m + memory: 256Mi + imagePullPolicy: Always + imagePullSecrets: + - name: harbor-registry-secret +''' +) { + + node(POD_LABEL) { + try { + stage('Update pipeline') { + echo("Pipeline updated") + } + + String branchName = '' + if (env.webhookBody) { + Map fullJSON = readJSON(text: webhookBody) + if (fullJSON.containsKey('head_commit')) { + String hashCommit = fullJSON['head_commit']['id'] + String shorthashCommit = hashCommit.substring(0, 10) + branchName = shorthashCommit + } else { + branchName = params.branch + } + } else { + branchName = params.branch + } + println 'branchName: ' + branchName + + if (params.onlyUpdatePipeline) { + currentBuild.result = 'SUCCESS' + return + } + + stage('Checkout source') { + git.clone(urlRepo: "${env.JENKINS_GIT_REPOSITORY_SSH_URL}/${gitRepoName}.git", + branch: branchName, + path: projectName, + disableSubmodules: true) + } + + stage('Get doxygen-awesome-css') { + String doxygenAwesomeUrl = 'https://nexus.avroid.tech/repository/devops-raw-custom-files/doxygen-awesome-css/doxygen-awesome-css-2.3.1.zip' + String doxygenAwesomeDir = 'doxygen-awesome-css' + dir(projectName) { + httpRequest ( + url: doxygenAwesomeUrl, + outputFile: doxygenAwesomeDir + ) + } + } + + String mainDocDir = 'documentation' + String projectDir = 'OS' + dateFormat = sh(returnStdout: true, script: "date '+%d-%m-%Y_%H-%M'").trim() + String publishDir = "${dateFormat}_${branchName}" + String mainHTMLFile = "main.html" + println 'Publish dir is: ' + publishDir + + stage('Generate documentation') { + dir(projectName) { + container(name: 'doxygen') { + script { + sh """ + doxygen + echo '${publishDir}' > documentation.html + """ + } + } + } + } + + stage('Generate main html file') { + dir(projectName) { + res = httpRequest( + url: "${env.JENKINS_NEXUS_URL}/service/rest/repository/browse/${nexusRepoName}/${mainDocDir}/${projectDir}", + httpMode: 'GET', + quiet: true, + validResponseCodes: "200,201,404", + authentication: "${env.JENKINS_NEXUS_CREDENTIALS}" + ) + + if (res.status != 404) { + String content = res.content + + def lines = content.readLines() + + java.util.regex.Pattern regexpPattern = (java.util.regex.Pattern)~/([0-9]+(-[0-9]+)+)_([0-9]+(-[0-9]+)+)_[A-Za-z0-9]+/ + + List docs = [] + + lines.each { line -> + def match = (line =~ regexpPattern) + + if (match) { + docs << match[0][0] + } + } + + println docs + + docs.each { doc -> + sh """ + echo '${doc}
' >> ${mainHTMLFile} + """ + } + } + sh """ + echo '${publishDir}' >> ${mainHTMLFile} + """ + } + } + + stage('Publish documentation') { + withCredentials([usernamePassword(credentialsId: "${env.JENKINS_NEXUS_CREDENTIALS}", + usernameVariable: 'USERNAME', + passwordVariable: 'PASSWORD')]) { + + dir("${projectName}/") { + res = httpRequest( + url: "${env.JENKINS_NEXUS_URL}/repository/${nexusRepoName}/${mainDocDir}/${projectDir}/${mainHTMLFile}", + authentication: env.JENKINS_NEXUS_CREDENTIALS, + httpMode: "PUT", + uploadFile: mainHTMLFile, + validResponseCodes: "201", + wrapAsMultipart: false + ) + + println("Status: "+res.status) + } + + dir("${projectName}/Eisen_Docs/html/") { + sh """ + find . -type f -exec curl -s --user ${USERNAME}:${PASSWORD} --ftp-create-dirs -T {} \ + ${env.JENKINS_NEXUS_URL}/repository/${nexusRepoName}/${mainDocDir}/${projectDir}/${publishDir}/html/{} \\; + """ + } + } + } + } catch (err) { + echo 'ERROR: ' + err.getMessage() + errorMessage = err.getMessage() + currentBuild.result = 'FAILURE' + } finally { + cleanWs() + } + } +} diff --git a/pipelines/jobs-dsl/jobs-dsl.groovy b/pipelines/jobs-dsl/jobs-dsl.groovy index f41bb4a..8bd1b4c 100644 --- a/pipelines/jobs-dsl/jobs-dsl.groovy +++ b/pipelines/jobs-dsl/jobs-dsl.groovy @@ -31,25 +31,25 @@ podTemplate(workspaceVolume: hostPathWorkspaceVolume(hostPath: "/data"), - name: harbor-registry-secret ''' ) { - node(POD_LABEL) { - stage('Get repository') { - def git = new Git(this, "$env.JENKINS_GIT_CREDENTIALS_SSH") - - git.clone([urlRepo: "$env.JENKINS_GIT_REPOSITORY_SSH_URL/$params.PROJECT_NAME", - branch: "$params.BRANCH_NAME"]) - } + node(POD_LABEL) { + stage('Get repository') { + def git = new Git(this, "$env.JENKINS_GIT_CREDENTIALS_SSH") - stage('Run job dsl') { - jobDsl( - targets: 'jobs-dsl/folders/*.groovy\n' + - 'jobs-dsl/jobs/**/*.groovy\n' + - 'jobs-dsl/views/**/*.groovy', - failOnSeedCollision: true, - lookupStrategy: 'JENKINS_ROOT', - removedJobAction: 'IGNORE', - removedViewAction: 'IGNORE', - removedConfigFilesAction: 'IGNORE' - ) - } - } + git.clone([urlRepo: "$env.JENKINS_GIT_REPOSITORY_SSH_URL/$params.PROJECT_NAME", + branch: "$params.BRANCH_NAME"]) + } + + stage('Run job dsl') { + jobDsl( + targets: 'jobs-dsl/folders/*.groovy\n' + + 'jobs-dsl/jobs/**/*.groovy\n' + + 'jobs-dsl/views/**/*.groovy', + failOnSeedCollision: true, + lookupStrategy: 'JENKINS_ROOT', + removedJobAction: 'IGNORE', + removedViewAction: 'IGNORE', + removedConfigFilesAction: 'IGNORE' + ) + } + } }