{"id":28209466,"url":"https://github.com/sunnywalden/gitlab-ci-cd-templates","last_synced_at":"2025-06-12T14:30:57.439Z","repository":{"id":46101511,"uuid":"221628383","full_name":"sunnywalden/gitlab-ci-cd-templates","owner":"sunnywalden","description":"gitlab CI/CD pipeline templates for java python and nodejs \\n java python 及node.js项目gitlab CI/CD模板","archived":false,"fork":false,"pushed_at":"2023-02-14T07:12:17.000Z","size":2942,"stargazers_count":16,"open_issues_count":0,"forks_count":11,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-17T15:14:47.582Z","etag":null,"topics":["auto-build","auto-test","cicd","code-check","gitlab-ci","maven","npm"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sunnywalden.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-11-14T06:33:09.000Z","updated_at":"2023-12-24T23:26:15.000Z","dependencies_parsed_at":"2022-09-01T09:12:40.099Z","dependency_job_id":null,"html_url":"https://github.com/sunnywalden/gitlab-ci-cd-templates","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/sunnywalden/gitlab-ci-cd-templates","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunnywalden%2Fgitlab-ci-cd-templates","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunnywalden%2Fgitlab-ci-cd-templates/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunnywalden%2Fgitlab-ci-cd-templates/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunnywalden%2Fgitlab-ci-cd-templates/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sunnywalden","download_url":"https://codeload.github.com/sunnywalden/gitlab-ci-cd-templates/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunnywalden%2Fgitlab-ci-cd-templates/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259482424,"owners_count":22864751,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auto-build","auto-test","cicd","code-check","gitlab-ci","maven","npm"],"created_at":"2025-05-17T15:14:21.152Z","updated_at":"2025-06-12T14:30:57.432Z","avatar_url":"https://github.com/sunnywalden.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# gitlab-ci-cd-templates\n\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](http://github.com/hhyo/archery/blob/master/LICENSE)\n\n## 版本依赖\n\ngitlab community edition  12.2.5\n\n## 说明\n\n基于gitlab CI/CD实现基于python3.7+、maven、nodejs开发应用从单元测试、构建到部署的全过程自动化。\n\n### 使用\n\n参照examples下的用例。\n\n\n\n # 功能概述\n\n提供代码质量自动检查机制（详细方案设计请见新CI方案）。\n\n![pipeline状态](pics/readme_pipeline_status.png)\n\n1.工程master或dev分支代码变更触发CI流程自动执行（粒度为服务级别，如merge请求同时修改了user及general，则整个CI流程仅针对user于general应用进行）；\n\n2.CI流程依次为： 【静态代码检查】--\u003e 【编译代码】--\u003e  【执行单元测试】--\u003e 【输出覆盖率报告】;\n\n3.主要输出包括代码质量分析、覆盖率详细报告及图表形式的覆盖率分析。\n\n# 项目上线示例\n\n## CI模板讲解\n\n注：此处指讲解java项目模板。\n\n1）申明采用的docker镜像\n\nimage: maven:3.6.2-jdk-8\n\n2）申明ci/cd全局变量\n\n```\n\nvariables:\n MAVEN_CLI_OPTS: \"-s /root/.m2/settings.xml --batch-mode\"\n MAVEN_OPTS: \"-Dmaven.repo.local=/root/.m2/repository\"\n POM_PATH: \"backend/user\"\n GIT_CLEAN_FLAGS: \"none\"\n GIT_DEPTH: \"3\"\n PRO_NAME: \"$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME\"\n SONAR_TOKEN: \"$SONAR_LOGIN\"\n SONAR_HOST_URL: \"$SONAR_URL\"\n SONAR_NAME: \"$SONAR_NAME\"\n\n```\n\n3）申明全局缓存\n\n```\ncache:\n paths:\n - /root/.m2/repository/\n - $POM_PATH/target/\n```\n\n4）定义预操作\n\n```\nbefore_script:\n - |\n echo 'deb http://mirrors.163.com/debian/ stretch main non-free contrib\n deb http://mirrors.163.com/debian/ stretch-updates main non-free contrib\n deb http://mirrors.163.com/debian/ stretch-backports main non-free contrib\n deb-src http://mirrors.163.com/debian/ stretch main non-free contrib\n deb-src http://mirrors.163.com/debian/ stretch-updates main non-free contrib\n deb-src http://mirrors.163.com/debian/ stretch-backports main non-free contrib\n deb http://mirrors.163.com/debian-security/ stretch/updates main non-free contrib\n deb-src http://mirrors.163.com/debian-security/ stretch/updates main non-free contrib' \u003e /etc/apt/sources.list\n - apt update\n - apt-get install -y mysql-client\n - pwd\n - |\n echo '\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n \u003csettings xsi:schemaLocation=\"http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd\" xmlns=\"http://maven.apache.org/SETTINGS/1.1.0\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\u003e\n \u003cservers\u003e\n \u003cserver\u003e\n \u003cusername\u003eadmin\u003c/username\u003e\n \u003cpassword\u003ePASSWORD\u003c/password\u003e\n \u003cid\u003ecentral\u003c/id\u003e\n \u003c/server\u003e\n \u003cserver\u003e\n \u003cusername\u003eadmin\u003c/username\u003e\n \u003cpassword\u003ePASSWORD\u003c/password\u003e\n \u003cid\u003esnapshots\u003c/id\u003e\n \u003c/server\u003e\n \u003c/servers\u003e\n \u003cprofiles\u003e\n \u003cprofile\u003e\n \u003crepositories\u003e\n \u003crepository\u003e\n \u003csnapshots\u003e\n \u003cenabled\u003efalse\u003c/enabled\u003e\n \u003c/snapshots\u003e\n \u003cid\u003ecentral\u003c/id\u003e\n \u003cname\u003elibs-release\u003c/name\u003e\n \u003curl\u003ehttp://ARTIFACTORYIP:9099/artifactory/libs-release\u003c/url\u003e\n \u003c/repository\u003e\n \u003crepository\u003e\n \u003cid\u003esnapshots\u003c/id\u003e\n \u003cname\u003elibs-snapshot\u003c/name\u003e\n \u003curl\u003ehttp://ARTIFACTORYIP:9099/artifactory/libs-snapshot\u003c/url\u003e\n \u003csnapshots\u003e\n \u003cenabled\u003etrue\u003c/enabled\u003e\n \u003cupdatePolicy\u003ealways\u003c/updatePolicy\u003e\n \u003c/snapshots\u003e\n \u003c/repository\u003e\n \u003c/repositories\u003e\n \u003cpluginRepositories\u003e\n \u003cpluginRepository\u003e\n \u003csnapshots\u003e\n \u003cenabled\u003efalse\u003c/enabled\u003e\n \u003c/snapshots\u003e\n \u003cid\u003ecentral\u003c/id\u003e\n \u003cname\u003elibs-release\u003c/name\u003e\n \u003curl\u003ehttp://ARTIFACTORYIP:9099/artifactory/libs-release\u003c/url\u003e\n \u003c/pluginRepository\u003e\n \u003cpluginRepository\u003e\n \u003csnapshots /\u003e\n \u003cid\u003esnapshots\u003c/id\u003e\n \u003cname\u003elibs-snapshot\u003c/name\u003e\n \u003curl\u003ehttp://ARTIFACTORYIP:9099/artifactory/libs-snapshot\u003c/url\u003e\n \u003c/pluginRepository\u003e\n \u003c/pluginRepositories\u003e\n \u003cid\u003eartifactory\u003c/id\u003e\n \u003c/profile\u003e\n \u003c/profiles\u003e\n \u003cactiveProfiles\u003e\n \u003cactiveProfile\u003eartifactory\u003c/activeProfile\u003e\n \u003c/activeProfiles\u003e\n \n \u003c/settings\u003e' \u003e /root/.m2/settings.xml\n```\n\n注：此处配置系统国内更新源及私有maven仓库配置、mysql客户端部署。\n\n5）定义代码检查job（借助sonarqube实现）\n\n```\n.sonarqube_job:\n stage: static_analysis\n variables:\n POM_PATH: \"backend/user\"\n script:\n - mvn -f $POM_PATH/pom.xml -Dsonar.projectKey=$SONAR_NAME -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_TOKEN verify sonar:sonar\n only:\n - merge_requests\n - branches\n allow_failure: true\n```\n\n6）定义单元测试job\n\n```\n.unit_test:\n stage: unit_test\n variables:\n POM_PATH: \"backend/user\"\n APP_NAME: \"user\"\n PRO_NAME: \"$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME\"\n before_script:\n script:\n - mvn $MAVEN_CLI_OPTS -f $POM_PATH/pom.xml test\n - cat $POM_PATH/target/site/jacoco/index.html\n after_script:\n - cat $POM_PATH/target/site/jacoco/index.html|grep -Eo \"Total.*?([0-9]{1,3})%\"|grep -Eo \"([0-9]{1,3})%\"|grep -Eo \"([0-9]{1,3})\"|head -n 1\n - COVER_VAL=`cat $POM_PATH/target/site/jacoco/index.html|grep -Eo \"Total.*?([0-9]{1,3})%\"|grep -Eo \"([0-9]{1,3})%\"|grep -Eo \"([0-9]{1,3})\"| head -n 1`\n - echo \"coverage value is $COVER_VAL\"\n - echo \"debug sql:\\n insert into coverage_report (app_name,project_path,branch_or_tag,commit_id,ci_job_id,coverage_value) values(\\\"$APP_NAME\\\", \\\"$PRO_NAME\\\", \\\"$CI_COMMIT_REF_NAME\\\", \\\"$CI_COMMIT_SHORT_SHA\\\", \\\"$CI_JOB_ID\\\", $COVER_VAL);commit;\"\n - mysql -h $MYSQL_HOST -u $MYSQL_USER -D $MYSQL_DATABASE -p$MYSQL_PASSWORD -e \"insert into $MYSQL_TABLE (app_name,project_path,branch_or_tag,commit_id,ci_job_id,coverage_value) values(\\\"$APP_NAME\\\", \\\"$PRO_NAME\\\", \\\"$CI_COMMIT_REF_NAME\\\", \\\"$CI_COMMIT_SHORT_SHA\\\", \\\"$CI_JOB_ID\\\", $COVER_VAL);commit;\"\n only:\n changes:\n - backend/user/*\n refs:\n - tech-4.2.0\n - merge_requests\n - master\n - tags\n allow_failure: true\n```\n\n7）覆盖率报告上传job\n\n```\n.pages:\n stage: unit_test\n variables:\n POM_PATH: \"backend/user\"\n# dependencies:\n# - .unit_test\n script:\n - mkdir -p public/$POM_PATH/\n - cp -r $POM_PATH/target/site/jacoco/* public/$POM_PATH/\n only:\n changes:\n - backend/user/*\n artifacts:\n paths:\n - public\n expire_in: 30 days\n allow_failure: true\n```\n\n8）制作并上传镜像到仓库\n\n```\n.build_image:\n stage: build_image\n image:\n name: kaniko-executor:debug\n entrypoint: [\"\"]\n before_script:\n - |\n echo \"\n {\n \"auths\":\n {\n \"$CI_REGISTRY\":\n {\n \"username\": \"$CI_REGISTRY_USER\",\n \"password\": \"$CI_REGISTRY_PASSWORD\"\n }\n },\n }\" \u003e /kaniko/.docker/config.json\n - |\n echo \"$REGISTRY_CERT\" \u003e\u003e /kaniko/ssl/certs/ca-certificates.crt\n - echo \"YOURIP XXXXX.com\" \u003e\u003e /etc/hosts\n - |\n echo \"\n {\n \"registry-mirrors\": [\n ],\n \"insecure-registries\": [\n \"XXXXX.com\"\n ],\n \"bip\":\"192.168.0.1/24\"\n }\" \u003e\u003e /kaniko/.docker/daemon.json\n - if [[ $CI_COMMIT_TAG ]];then echo \"image $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG\";fi\n - if [[ $CI_COMMIT_TAG == \"\" ]];then echo \"$CI_REGISTRY_IMAGE:latest\";fi\n script:\n - if [[ $CI_COMMIT_TAG ]] \u0026\u0026 [[ $CI_COMMIT_TAG != \"latest\" ]];then /kaniko/executor --context $(pwd)/$CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG --skip-tls-verify-registry $CI_REGISTRY;fi\n - /kaniko/executor --context $(pwd)/$CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE:latest --skip-tls-verify-registry $CI_REGISTRY\n only:\n refs:\n - master\n```\n\n## 项目变量配置\n\n进入项目【设置】-【CI/CD】-【变量】\n\n![ci/cd](pics/ci_cd_all.png)\n\n## 定义变量\n\n![ci变量](pics/ci_varibles.png)\n\n## 项目CI设置\n\n进入项目【设置】-【CI/CD】-【通用 pipelines】。\n\n1）触发pipeline代码行为定义，一般默认fetch即可。建议开启浅拷贝，值在1-5之间。\n\n![ci拉代码策略](pics/ci_git_policy.png)\n\n2）Timeout最好做自定义（15-30m之间？），否则出现异常可能会导致合并代码等操作挂起。\n\n3）.gitlab-ci.yml位置，保持默认值即可。\n\n4）覆盖率正则表达式，建议拷贝项目开发语言对应推荐正则即可。\n\n![覆盖率正则表达式](pics/coverage_regexs.png)\n\n5）pipeline状态及覆盖率结果badge，选择对应分支，将markdown格式的链接贴到readme即可。\n\n## 项目.gitlab-ci.yml配置\n\n实际上此处仅仅是对模板简单的重用，对pipeline各个job个性化的部分进行重载。\n\n1）引用模板\n\n```\ninclude:\n project: 'sunnywalden/ci-templates'\n ref: master\n file: '/templates/.gitlab-ci-maven-template.yml'\n```\n\n2）申明全局变量\n\n```\nvariables:\n GIT_DEPTH: \"1\"\n GIT_CLEAN_FLAGS: \"none\"\n MYSQL_HOST: \"127.0.0.1\"\n MYSQL_DATABASE: \"unit_test\"\n MYSQL_USER: \"test\"\n MYSQL_PASSWORD: \"123456\"\n```\n\n3）静态代码检查\n\n重载模板中名为.sonarqube_job的job即可，差异化的点在于pom文件路径、sonarqube项目配置这几个变量值不同，以及代码路径不同，还有就是触发job的场景可能不同。\n\n```\nstatic_portfolio:\n variables:\n POM_PATH: \"backend/portfolio\"\n SONAR_NAME: \"$PORTFOLIO_SONAR_PRO\"\n SONAR_TOKEN: \"$PORTFOLIO_SONAR_TOKEN\"\n extends:\n .sonarqube_job\n only:\n refs:\n - merge_requests\n changes:\n - backend/portfolio/*\n```\n\n4）编译\n\n重载模板中名为.build的job即可，差异化的点在于pom文件路径变量值不同，以及代码路径不同，还有就是触发job的场景可能不同。\n\n```\nbuild_portfolio:\n variables:\n POM_PATH: \"backend/portfolio\"\n extends:\n .build\n only:\n refs:\n - merge_requests\n changes:\n - backend/portfolio/*\n```\n\n5）单元测试\n\n重载模板中名为.unit_test的job即可，差异化的点在于pom文件路径变量值不同，以及代码路径不同，还有就是触发job的场景可能不同。\n\n```\ntest_top2:\n variables:\n POM_PATH: \"backend/top\"\n APP_NAME: \"top\"\n extends: .unit_test\n only:\n changes:\n - backend/top/*\n refs:\n - merge_requests\n```\n\n6）覆盖率报告上传到pages\n\n重载模板中名为.pages的job即可，差异化的点在于pom文件路径变量值不同，以及代码路径不同，还有就是触发job的场景可能不同。\n\n```\npages_top2:\n variables:\n POM_PATH: \"backend/top\"\n extends: .pages\n only:\n changes:\n - backend/top/*\n refs:\n - merge_requests\n```\n\n# 结果示例\n\n## 修改所有后端应用代码并merge到dev分支\n\n![代码更新](pics/code_update.png)\n\n## 自动触发CI流程\n\npipeline详情\n\n![pipeline详情](pics/pipeline_details.png)\n\n3.3 输出报告\n\n\n\n### 覆盖率详情静态页面报告\n\n1)报告获取\n\n进入gitlab该工程主页；\n\n进入pipeline页；\n\n找到对应的pipeline，点击右侧附件下载按钮，下载静态报告；\n\n![pipeline列表](pics/pipeline_lists.png)\n\n解压下载的附件，通过浏览器打开对应应用路径下的index.html;\n\n![覆盖率报告文件](pics/coverage_report_files.png)\n\n2）报告详情实例 \n \n![覆盖率详情](pics/coverage_details.png)\n\n### 覆盖率分析图表\n\n\n![dashboard](pics/coverage_grafana_dashboard.png)\n\n注：Grafana模板见grafana_templates/coverage_dashboard.json。\n\n### 代码质量分析结果\n\n\n![sonarqube](pics/sonarqube_projects.png)\n\n详情\n\n![代码质量](pics/code_quality_details.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunnywalden%2Fgitlab-ci-cd-templates","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsunnywalden%2Fgitlab-ci-cd-templates","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunnywalden%2Fgitlab-ci-cd-templates/lists"}