{"componentChunkName":"component---src-templates-post-template-jsx","path":"/works/posts/2021-01-23--002","result":{"data":{"site":{"siteMetadata":{"title":"Blog by Eunyoung","subtitle":"작업 기록 블로그","copyright":"© All rights reserved.","author":{"name":"EunYoung","twitter":"#"},"disqusShortname":"","url":"https://ssongey.github.io"}},"markdownRemark":{"id":"1b11be0b-e7fa-50d5-b4fd-8bc7cef480a7","html":"<p><span class=\"title__sub1\"> Sonarqube ? </span></p>\n<ul>\n<li>20개 이상의 프로그래밍 언어에서 버그, 코드 스멜, 보안 취약점을 발견할 목적으로 정적 코드 분석으로 자동 리뷰를 수행하기 위한 지속적인 코드 품질 검사용 오픈 소스 플랫폼 </li>\n<li>중복 코드, 코딩 표준, 유닛 테스트, 코드 커버리지, 코드 복잡도, 주석, 버그 및 보안 취약점의 보고서를 제공.</li>\n<li>sonar scanner에게 정적 분석 관련 데이터 제공</li>\n</ul>\n<br>\n<p><span class=\"title__sub1\"> 정적분석을 위한 Sonarqube 설치 </span></p>\n<ul>\n<li><a href=\"https://hub.docker.com/_/sonarqube/\">https://hub.docker.com/_/sonarqube/</a></li>\n</ul>\n<p><span class=\"title__sub2\">1. host 설정</span></p>\n<ul>\n<li>sonarqube 내부에 Elasticsearch 를 사용하고 있기 때문에 필요 설정이 있다\n\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/7a24aa1ce8afd1f2e94e6157c789e279/e619b/002-01.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 787px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 38.75%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABFElEQVQoz5WS6XKDMAyE/f5P2XaSkHAYXxiDIRutSDNp/8UzHysLRiemsw6npkXT9srX6YLztcX3ucHgPHju9zsff5Tsu/CrT9ukKcOHeBATnKjzAcPoENOEsizK8tIVpSyYhWkuwoxMzbP6zBgSWpfQ+UOHkNH7CVcbcBsjWuvRjUHvrYvquwweYWKAokGZiMrAhlU1vUXvgtJJAOujkMBkltWKnzZxcdL3XqpPOSNKh078rJDHsC0rs2KrQYKzdWbe9x21VqxP6j/Uvx4s66p3ztVwJjFlzPOimazj/Lza27Zjq5vodug72zvHd1UwTsr/Od9ks51uu5etk1LWVwWfYLiZIHMZJXDORefAX4CZa/2cB6aQbL0or2ucAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"002 01\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/7a24aa1ce8afd1f2e94e6157c789e279/e619b/002-01.png\"\n        srcset=\"/devHistoryBlog/static/7a24aa1ce8afd1f2e94e6157c789e279/8ff5a/002-01.png 240w,\n/devHistoryBlog/static/7a24aa1ce8afd1f2e94e6157c789e279/e85cb/002-01.png 480w,\n/devHistoryBlog/static/7a24aa1ce8afd1f2e94e6157c789e279/e619b/002-01.png 787w\"\n        sizes=\"(max-width: 787px) 100vw, 787px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\"># max_map_count ?\nThis file contains the maximum number of memory map areas a process may have. Memory map areas are used as a side-effect of calling malloc, directly by mmap and mprotect, and also when loading shared libraries.\nWhile most applications need less than a thousand maps, certain programs, particularly malloc debuggers, may consume lots of them, e.g., up to one or two maps per allocation.\nThe default value is 65536.</code></pre></div>\n<br>\n<p><span class=\"title__sub2\">2. DB 및 Volumes 설정 내용 </span>\n\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/5ab97f9516fe199f8f2313f58a223c46/0f67e/002-02.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 921px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 58.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAABT0lEQVQoz5VSCW6EMAzM/7/Zll2uHJBwB9fjEHZXQqhFGtkGfIzH6utR0bNuyXY94dn3/QS9+VfxFdRPWVMYxpTwx+e2YNlo8mEgPww0jJP4vQ+nxTs0BDqOp3m5baZAtagaarSl1rjT1rDWkbadADG+GddJYcd58JEPaPbXbSOFj6D94D0WZSN+gZibANhvslrw/cS/bGtDBQP53cEogrK2aSrp2vujuz/jPsAywkRumMj6kSz7Nswcz+SnhcZle1EG3ao1Mu62RYoxigXwLsb9X+KoPAn2lPeRdwfrWYxNmiWs60oLA/5lwcDqVqw00JpPQeAL2LeHCFhPzYw6HuJqUoXTSIuvmbo+E6FaVt24npsYKdyYVyOww7TvRRXuq+GfAUxoOEnE6dMq8mngHpGAHWekHcfPglAUZ4HEnJysl8lwBZgWFPFtWdZbcX4BkPCjJeTqvfkAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"002 02\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/5ab97f9516fe199f8f2313f58a223c46/0f67e/002-02.png\"\n        srcset=\"/devHistoryBlog/static/5ab97f9516fe199f8f2313f58a223c46/8ff5a/002-02.png 240w,\n/devHistoryBlog/static/5ab97f9516fe199f8f2313f58a223c46/e85cb/002-02.png 480w,\n/devHistoryBlog/static/5ab97f9516fe199f8f2313f58a223c46/0f67e/002-02.png 921w\"\n        sizes=\"(max-width: 921px) 100vw, 921px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br>\n<p><span class=\"title__sub2\">3. Compose 파일 작성</span></p>\n<ul>\n<li>sonarqube develop edition 버전 설치 (trial 라이센스 문의 함)</li>\n<li>embedded db : postgres 사용</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">version: &quot;3.7&quot;\nservices:\n  db:\n    image: postgres\n    container_name: sonar-postgres\n    restart: always\n    environment:\n      POSTGRES_USER: sonar\n      PASTGRES_PASSWORD: sonar\n      TZ: Asia/Seoul\n      POSTGRES_HOST_AUTH_METHOD: trust\n    volumes:\n      - ~/docker-volumes/sonar-postgres/postgres:/var/lib/postgresql/data\n  \n  sonarqube:\n    image: sonarqube:8.6.1-developer\n    container_name: sonarqube\n    restart: always\n    environment:\n      SONARQUBE_HOME: ./\n      SONARQUBE_JDBC_USERNAME: sonar\n      SONARQUBE_JDBC_PASSWORD: sonar\n      SONARQUBE_JDBC_URL: jdbc:postgresql://db:5432/sonar\n    depends_on:\n      - db\n    ports:\n      - 10002:9000\n    volumes:\n      - ~/docker-volumes/sonar-postgres/sonarqube/data:/opt/sonarqube/data\n      - ~/docker-volumes/sonar-postgres/sonarqube/extensions:/opt/sonarqube/extensions\n      - ~/docker-volumes/sonar-postgres/sonarqube/logs:/opt/sonarqube/logs\n      - ~/docker-volumes/sonar-postgres/temp:/opt/sonarqube/temp</code></pre></div>\n<br>\n<p><span class=\"title__sub2\">4. 서비스 기동</span></p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">$ docker-compose -f sonarqube-compose.yml up -d</code></pre></div>\n<br>\n<p><span class=\"title__sub1\"> 정적분석을 위한 Sonarqube 프로젝트 생성 및</span> </p>\n<p><span class=\"title__sub2\">1. Sonarqube 프로젝트 생성</span></p>\n<ul>\n<li>10002 포트로 접속 후 로그인 &#x26; 프로젝트 생성\n\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/1ec4e0187cad189410f134a4520be1a9/eea79/002-05.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 502px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 77.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABJ0AAASdAHeZh94AAAB7UlEQVQ4y51U2ZKbMBDk//9r31K1VCWEG4MtcUqAkMBHkupIwnYZZ3ezyUMzYhjaPT2DnbZtEQQB4ji2kRCCNE0RmXvfB6EU8zxjmiZIKf8KhzFmycIwtCiK4k7ueR7quoZSyhJ+Bo7UxcuyWByPR6vm8f5fyFZCI1VtZT8XvdXae8+cRrfkuq5u7xviMEJFSwzDaIuFEJiEfvEeV5j8LGcc1RFiEluFXHRIyhRFVaDuK6iLgjzrX75IfZY2PuP084R0TOHWLi7L5aFDTdgNmpAmyEiGXbkDZRSVJqacguiziSZX8tKCdAQVrxBVEcImBG8ZzGBXhdcpZ1mqkaHYF8jzHZIksRNPr/kojmyMdT4IfLtS+S4HLYjNd11nbbAe9pyDEoq2aS14x9AzDjHqgmk135xX7x7PAly/a3K3TbAt102F16+v+B758GMfaZ6iYQ1GOWKYBgzybQgpLNFt4mvUCrnstB8xsjJDq8/ql4K4CIynEeP5TwynAfOPGR7z8EJecFLnzaQdxhn25QEHjT3VIAXKprQK34NRxwUHEwxKqs1OOsYLMY5214Z+sL6YPTT+fQRDdCPbfsv9iC9BDjc5oOW6nfnqizb4Qzyo2igc9NR2tEFetuiNsqeCz/7L3BWay6JVLbP6L4Jn/AZCFrnpIWYSSAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"002 05\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/1ec4e0187cad189410f134a4520be1a9/eea79/002-05.png\"\n        srcset=\"/devHistoryBlog/static/1ec4e0187cad189410f134a4520be1a9/8ff5a/002-05.png 240w,\n/devHistoryBlog/static/1ec4e0187cad189410f134a4520be1a9/e85cb/002-05.png 480w,\n/devHistoryBlog/static/1ec4e0187cad189410f134a4520be1a9/eea79/002-05.png 502w\"\n        sizes=\"(max-width: 502px) 100vw, 502px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    \n<br></li>\n<li>프로젝트 토큰 생성\n\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/dcd094aa105fa8673ecc2a2b2322129a/e619b/002-06.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 787px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 32.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABJ0AAASdAHeZh94AAAAyUlEQVQY052QSW7DMAxFff+T5QrdBgZaI7asyRY1+Zdku8jgbELgix+U9CRyuHyNuE4GtG8IIYKIcBwHeu8PaqLWXurPGsbFY3aRYQHOOXjvFfhpDLKkXDHNBtYHbCmDSkNpHflf4v1O+DFBz0rIo2caZCm1YVktVucR94RcuT3+JCeV+EgFk4269y4UKKbVqi1ba2GMQYgRiWeZkijpXDOrt6qZ6K6es/pSyl/LMkgpLAxyDJQ53ozF97wyeHsE8GU6AUoWoLB+AYqV1dx35lX0AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"002 06\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/dcd094aa105fa8673ecc2a2b2322129a/e619b/002-06.png\"\n        srcset=\"/devHistoryBlog/static/dcd094aa105fa8673ecc2a2b2322129a/8ff5a/002-06.png 240w,\n/devHistoryBlog/static/dcd094aa105fa8673ecc2a2b2322129a/e85cb/002-06.png 480w,\n/devHistoryBlog/static/dcd094aa105fa8673ecc2a2b2322129a/e619b/002-06.png 787w\"\n        sizes=\"(max-width: 787px) 100vw, 787px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    \n<br></li>\n<li>을 하면 아래와 같이 sonar scanner 를 사용하기 위한 설정 방법이 나온다.\n\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/bf81404469ad3593a0cd1a85abd3233d/c65fa/002-04.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 40.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA5UlEQVQY032Pa27DIBCEuf+VeoRGiZp/VlvXJDwSm4cxScCAcZe4rdoqySexrAQ7s4MGe/LexxhzztMd8pTHNDrvtNKUUsYYVCEE4nIwxpRjTH7InOd/IBB+o+3T+vWojD45bZ2yLqRpfsgih2JMxXgYFntrLURIKcUQliaEAAY3JRC8NU2DMd4Duz37hhICwTjjhBDOefcLITrKD62Q4By1UpC+7/vz+eK8H2/h/3Jx5WMZ3mFcv9f4CvhIKRWw1HJ/NT+AWdsJpfsyDOvV9cfLdvu8Wq03m6qqrrvdRQpxOLZS609PVcbRJnviqQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"002 04\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/bf81404469ad3593a0cd1a85abd3233d/d9199/002-04.png\"\n        srcset=\"/devHistoryBlog/static/bf81404469ad3593a0cd1a85abd3233d/8ff5a/002-04.png 240w,\n/devHistoryBlog/static/bf81404469ad3593a0cd1a85abd3233d/e85cb/002-04.png 480w,\n/devHistoryBlog/static/bf81404469ad3593a0cd1a85abd3233d/d9199/002-04.png 960w,\n/devHistoryBlog/static/bf81404469ad3593a0cd1a85abd3233d/c65fa/002-04.png 1434w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </li>\n</ul>\n<br>\n<p><span class=\"title__sub2\">2. Scanner 설정 및 실행</span></p>\n<ul>\n<li>build.gradle에 plugin 추가 후</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\">plugins <span class=\"token punctuation\">{</span>\n  id <span class=\"token string\">\"org.sonarqube\"</span> version <span class=\"token string\">\"3.0\"</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<ul>\n<li>scanner 를 실행하면</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">./gradlew sonarqube \\\n  -Dsonar.projectKey=Test-Proj \\\n  -Dsonar.host.url=http://HOST:10002 \\\n  -Dsonar.login=***********************</code></pre></div>\n<ul>\n<li>정적분석 결과가 표시된다.</li>\n</ul>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/3adf418ed240c4d33879ddf364d05ad9/951a4/002-07.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 56.25%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABJ0AAASdAHeZh94AAABx0lEQVQoz31TzU4UQRjsI+HCjSuPoO/BEZ9tozcSD55Eohev+grGGE0AXRKMuLsz/f8z3VNW9wwbFgmTVDrTPV1f1VffCKcToowYLQBPJCB4jxACxnHEWApKyUTBEBSCW8Pajueeq4VUCr026JVBSgPEux/v8fLLKyy+LrD4tsDp91Msb5boNx0/0rjdSHT8WPGi0hqalyfotielnM9MOxfHn46xd7YH8UZAvBbYf7uPn+tf0MohxABPpZnqUqKTGB+Fcw7eSBitIE4+v8DB2QGOPhzh8PwQzz8+wx+7IlGm5YLpGfHUM+SM7CVsJbzeXONidYHL1WVbr9ZXVBbZo0hVcerjHSr1/fcZzQHbYwjhDK0ZWjN+ixgTFUbknHcvDkML5yFhC4wBmdrD1lglt1CEp0LrQ0u79g6zskhLnnsDie/2CotWR6XXsOQSuiWn59TqytGgQmn9f2o6O4W0Q8g+12C60EGZh4R1ZZVIVcanRoh7sWgfW7GcyzamSloL6KgeIZxnLUXP2euw/MtRcKENt7J+ZjAw5ha/17qlWwv02rajOug7hNVutV3/At8wWaxp1z4lKhmSQwym7Yd5Dmtf00BXxuAfwdhBAMiGlFcAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"002 07\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/3adf418ed240c4d33879ddf364d05ad9/d9199/002-07.png\"\n        srcset=\"/devHistoryBlog/static/3adf418ed240c4d33879ddf364d05ad9/8ff5a/002-07.png 240w,\n/devHistoryBlog/static/3adf418ed240c4d33879ddf364d05ad9/e85cb/002-07.png 480w,\n/devHistoryBlog/static/3adf418ed240c4d33879ddf364d05ad9/d9199/002-07.png 960w,\n/devHistoryBlog/static/3adf418ed240c4d33879ddf364d05ad9/951a4/002-07.png 1355w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br>\n<p><span class=\"title__sub1\">Pipeline 작성</span>\n<span class=\"title__sub2\">1. Test Stage</span></p>\n<ul>\n<li>테스트 코드를 수행한다.</li>\n<li>테스트 실패 시 테스트 결과 게시 및 PR comment &#x26; decline api 전송 후 파이프라인을 종료한다.</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">stage (&#39;Test&#39;) {\n    sh &#39;&#39;&#39;\n    {\n        ./gradlew test \\\n        &amp;&amp; curl -X POST -u &quot;$USER&quot; $COMMENT_URL -d &#39;{&quot;content&quot;: {&quot;raw&quot;: &quot;[TEST] SUCCESS&quot;}}&#39; -H &#39;Content-Type: application/json&#39; &gt; /dev/null 2&gt;&amp;1 \\\n        &amp;&amp; echo [TEST] SUCCESS;\n    }||\\\n    {\n        ssh -ir ~/.ssh/v2g_srv $V2G_DEV_SERVER bash -c &quot;&#39;mkdir -p /docker-volumes/nginx/html/failed-test/$SOURCE_BRANCH&#39;&quot;;\n        scp -ir ~/.ssh/v2g_srv ./build/reports/tests/test $V2G_DEV_SERVER:/docker-volumes/nginx/html/failed-test/$SOURCE_BRANCH;\n        curl -X POST -u &quot;$USER&quot; $COMMENT_URL -d &#39;{&quot;content&quot;: {&quot;raw&quot;: &quot;[TEST] FAIL&quot;}}&#39; -H &#39;Content-Type: application/json&#39; &gt; /dev/null 2&gt;&amp;1;\n        curl -X POST -u &quot;$USER&quot; $DECLINE_URL -d &#39;{&quot;content&quot;: {&quot;raw&quot;: &quot;[TEST] FAIL&quot;}}&#39; -H &#39;Content-Type: application/json&#39; &gt; /dev/null 2&gt;&amp;1;\n        echo [TEST] FAIL;\n        exit 1;\n    }\n    &#39;&#39;&#39;\n}</code></pre></div>\n<br>\n<p><span class=\"title__sub2\">2. Jacoco &#x26; SonarQube Analysis &#x26; Quality Gate</span></p>\n<ul>\n<li>테스트 성공 시 coverage 측정 및 정적분석 진행 후 Quality Gate 결과 확인</li>\n<li>Qulicy Gate 실패 시 PR comment &#x26; decline api 전송 후 파이프라인을 종료한다.</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">stage (&#39;Jacoco &amp; SonarQube Analysis &amp; Quality Gate&#39;) {\n    withSonarQubeEnv(&#39;sonarqube&#39;) {\n        sh &quot;./gradlew jacocoTestReport sonarqube&quot;\n    }\n    \n    def qg = waitForQualityGate()\n    if (qg.status != &#39;OK&#39;) {\n        sh &#39;&#39;&#39;\n            curl -X POST -u &quot;$USER&quot; $COMMENT_URL -d &#39;{&quot;content&quot;: {&quot;raw&quot;: &quot;[QualityGate] FAIL&quot;}}&#39; -H &#39;Content-Type: application/json&#39; &gt; /dev/null 2&gt;&amp;1;\n            curl -X POST -u &quot;$USER&quot; $DECLINE_URL -d &#39;{&quot;content&quot;: {&quot;raw&quot;: &quot;[QualityGate] FAIL&quot;}}&#39; -H &#39;Content-Type: application/json&#39; &gt; /dev/null 2&gt;&amp;1;\n            echo [TEST] FAIL;\n            exit 1;\n        &#39;&#39;&#39;\n    } else {\n        sh &#39;&#39;&#39;\n            curl -X POST -u &quot;$USER&quot; $COMMENT_URL -d &#39;{&quot;content&quot;: {&quot;raw&quot;: &quot;[QualityGate] SUCCESS&quot;}}&#39; -H &#39;Content-Type: application/json&#39; &gt; /dev/null 2&gt;&amp;1;\n        &#39;&#39;&#39;\n    }\n}</code></pre></div>\n<br>\n<p><span class=\"title__sub2\">3. Approve PullRequest</span></p>\n<ul>\n<li>해당 PR에 대한 승인 API 전송 후 파이프라인 종료</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">stage (&#39;Approve PR&#39;) {\n    timeout(time: 1, unit: &#39;MINUTES&#39;) {\n        sh &#39;&#39;&#39;\n            curl -X POST -u &quot;$USER&quot; $APPROVE_URL;\n            echo Approve PullRequest;\n        &#39;&#39;&#39;\n    }\n}</code></pre></div>\n<hr>\n<p><a href=\"https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-18--001\">> [작업로그] CI/CD 구축 #1 - CI/CD 시나리오</a><br>\n<a href=\"https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-18--002\">> [작업로그] CI/CD 구축 #2 - Docker, Docker Compose 설치</a><br>\n<a href=\"https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-18--003\">> [작업로그] CI/CD 구축 #3 - BitBucket 설정 및 Jenkins 설치</a><br>\n<a href=\"https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-21--001\">> [작업로그] CI/CD 구축 #4 - Jenkins Item 등록 및 Pipeline 작성</a>  </p>","fields":{"tagSlugs":["/tags/ci-cd/","/tags/sonarqube/","/tags/pipeline/"],"slug":"/works/posts/2021-01-23--002"},"frontmatter":{"title":"[작업로그] CI/CD 구축 #5","tags":["ci/cd","sonarqube","pipeline"],"date":"2021-01-23","description":"sonarqube 설치 및 pipeline 작성"}}},"pageContext":{"slug":"/works/posts/2021-01-23--002"}},"staticQueryHashes":[]}