# CI/CD(持續性整合/ 部署) ![](https://hackmd.io/_uploads/HyUCJ3Gep.png) 簡單介紹CI/CD {%youtube eOlI6-BBN4E %} ## 持續整合 是一種軟體工程流程,是將所有軟體工程師對於軟體的工作副本持續整合到共享主線(mainline)的一種舉措。該名稱最早由葛來迪·布區(Grady Booch)在他的布區方法中提出,在測試驅動開發(TDD)的作法中,通常還會搭配自動單元測試。持續整合的提出主要是為解決軟體進行系統整合時面臨的各項問題,極限編程稱這些問題為整合地獄(integration hell)。 ### CI的目的 1. 降低風險。 2. 減少人工手動的繁複程序。 3. 可隨時產生一版可部署的版本。 4. 增加系統透明度。 ### 驗證 1. 建置(build) 2. 測試(test) 3. [程式碼分析(source code analysis)](#弱點掃描) 驗證完成後,進一步可以[自動化發佈或部署 (Continuous Delivery / Continuous Deployment)](#持續部署) ## 持續交付&持續部署 **持續交付**(Continuous Delivery - CD)和**持續部署**(Continuous Deployment - CD)是CI/CD過程的關鍵組成部分,它們旨在實現自動化的軟體發布流程,從開發到生產環境的交付,以確保高質量、快速和可靠的軟體交付。 ### 持續交付(Continuous Delivery - CD): 持續交付是一種自動化軟體交付流程,旨在確保每個代碼更改都可以隨時部署到生產環境,但尚未實際部署。關鍵特點包括: * **自動化測試**:持續交付包括廣泛的自動化測試,包括單元測試、集成測試、功能測試和性能測試。這些測試確保每個代碼更改都不會引入新問題。 * **自動化構建**:持續交付還包括自動化構建過程,將代碼編譯為可執行的軟體包。 * **自動化部署到預生產環境**:持續交付會自動將應用程序部署到一個預生產環境(通常是與生產環境相似的環境),以確保在生產環境之前進行最後的驗證和測試。 * **隨時可部署**:通過持續交付,團隊可以隨時選擇部署新版本。這意味著新功能和修復可以在需要時非常迅速地交付給用戶。 * **手動審批**:通常,持續交付需要人工審批,以確保最終的部署決策。 ### 持續部署(Continuous Deployment - CD): 持續部署是CI/CD過程的進一步自動化,它不僅包括了持續交付的所有步驟,還將每個通過測試的代碼更改自動部署到生產環境,沒有人為干預。關鍵特點包括 * **自動化部署到生產環境**:持續部署的最大區別是自動化部署到生產環境。一旦代碼通過了所有測試,它就會自動部署到生產環境,而無需等待人工批准。 * **迅速的交付**:持續部署能夠實現極快的交付速度,因為沒有手動部署的延遲。 * **高度自動化**:除了生產環境之外,持續部署還會自動化各個環節,從代碼合併到部署都不需要人工干預。 * **快速反饋迴路**:持續部署允許團隊快速獲取用戶反饋,因為新功能和改進幾乎立即可用。 ## 程式碼分析 ### 弱點掃描工具 - OWASP ZAP 開放式Web應用程式安全專案(OWASP)是一個線上社群 OWASP Zed Attack Proxy (簡稱 ZAP) 於2010年9月由 Open Web Application Security Project (OWASP) 開發,目前為全世界最受歡迎的網頁程式漏洞檢測工具。 自 2023 年 8 月 1 日起,ZAP 開發團隊宣布 OWASP ZAP 將離開 OWASP 基金會,加入軟體安全項目,作為創始項目,此後將簡稱為ZAP。 自動化測試:可以將ZAP整合到自動化測試工作流程中,以便定期掃描網路應用程式以偵測新的漏洞。這對於持續整合和持續交付(CI/CD)流程非常有用。 [官方載點](https://www.zaproxy.org/download/) ***ZAP畫面*** ![](https://hackmd.io/_uploads/rJhCvnflp.png) ![](https://hackmd.io/_uploads/HJZ8F3fgT.png) ![](https://hackmd.io/_uploads/SkLFY3ze6.png) ## Jenkins @jj-xt3IISSqJHOLC-qLIng ### Pipeline Jenkins Pipeline 是一組 plugin,可支援實作以及將持續整合 pipeline 整合至 Jenkins 中,而持續整合 pipeline 是一個自動化的表達式 (automated expression),表現了軟體由版本控制系統到用戶的全部過程。 Jenkins Pipeline 提供了豐富的工具組合,可用來表示各種簡單至複雜的過程,並將它們以程式碼的方式呈現,也就是 Jenkinsfile,可稱為 pipeline-as-code,將持續整合 pipeline 也視為應用程式中需被版本管理及審閱的程式碼的一部分。 Jenkinsfile 的內容,不是 JSON、YAML 也不是 INI,這裡提到這種語法稱為 Pipeline Domain Specific Language (Pipeline DSL),一般來說可以用 Declarative 和 Script 的兩種寫法,目前的文件介紹都是以 Declarative 的寫法為主。 Pipeline 在 Jenkins 的建立方法有兩種,一種是直接在 Web UI 上建立編寫,第二種是使用 Jenkinsfile 並將它簽入到版控系統之中。 #### 為什麼要使用 Pipeline 呢?有以下的好處: 1. **代碼化**:將 Pipeline 代碼化,讓團隊可以編輯、審閱並迭代,意思大概是指可以根據先前的 Pipeline 內容進行優化,以改善流程。 2. **可持續**:這一句看不太懂,原文是這樣: Pipelines can survive both planned and unplanned restarts of the Jenkins master,好像是說 Jenkins 伺服器無論是有意或無意的重啟,Pipeline 都能持續運作。 3. **可暫停**:可在過程中安插中斷點,讓人為決定 Pipeline 是否繼續執行。 4. **多樣化**:Pipeline 可支援極複雜的持續交付流程需求,例如 fork/join、loop 及平行多工。 5. **可擴展**:Pipeline 的插件支援對 Pipeline DSL 的客製擴展 (custom extensions)。 以下這張圖示範了一個可以使用 Jenkins 來建立模型的持續整合流程。 ![](https://hackmd.io/_uploads/rkYz93zg6.png) ### [Groovy](https://ithelp.ithome.com.tw/m/articles/10157426) 查詢韋氏字典(Merriam-Webster),可以發現 Groovy 單字的定義是「very good and enjoyable」。學習 Groovy 程式語言的過程中,可以發掘許多 Groovy 帶來的樂趣,並且能夠用它輕鬆完成許多任務。 ### Build @Vincentl92 ![](https://hackmd.io/_uploads/r1sC1hzlT.png) ![](https://hackmd.io/_uploads/HJSTz3zeT.png) ```! Builds CI build tools automatically package up files and components into release artifacts and run tests for quality, performance, and other requirements. After clearing required checks, CD tools send builds off to the operations team for further testing and staging. ``` "Build"流程是整個持續集成和持續部署過程的一部分,它的主要目標是將代碼編譯、構建成可執行的軟件包或應用程序,以便在後續的階段進行測試、部署和交付。下面是CI/CD中"Build"流程的主要步驟和內容: ![](https://hackmd.io/_uploads/B1vWb3zg6.jpg) * 代碼檢查: 在開始建置之前,CI/CD流程通常會對代碼庫中的更改進行檢查。這可能包括代碼風格檢查、代碼質量檢查、靜態代碼分析等。這些步驟有助於確保代碼的質量和一致性。 * 依賴解析: 如果應用程序依賴於外部庫或模塊,則需要解析這些依賴關係。這可能涉及下載所需的庫、模塊或依賴項。 * 編譯/構建: 這是Build流程的核心步驟。在此階段,代碼被編譯成可執行的二進制文件,或者如果是Web應用程序,則可能包括將代碼轉換為靜態資源(例如HTML、CSS、JavaScript等)。這也包括代碼的打包和壓縮。 * 單元測試: 在建置完成後,通常會運行單元測試來確保代碼的基本功能正常工作。單元測試應該涵蓋代碼的各個部分,並檢查它們的行為是否如預期。 * 生成可部署輸出: 建置過程可能會生成一個或多個可部署的輸出。這取決於您的應用程序類型,可以是二進制可執行文件、Docker映像、Web應用程序資源等。 * 文檔生成: 建置過程還可以生成文檔,例如API文檔、使用手冊或自動生成的代碼註釋。 * 軟件版本號生成: 您可以生成一個唯一的軟件版本號,以便在部署和版本控制中使用。 * 存儲輸出物件: 建置過程完成後,輸出文件通常存儲在特定位置,以便在後續的階段進行使用。這些位置可能是Artifactory、Docker Hub、內部伺服器等。 * 通知和日誌: 在建置過程完成後,通常需要生成通知(例如Slack通知或郵件通知)以通知團隊建置的狀態。同時,也應該生成日誌以記錄建置過程的詳細信息,以便進行故障排除。 總之,"Build"流程是CI/CD管道中的一個關鍵步驟,它將代碼轉換為可執行的軟件或應用程序。它有助於確保代碼的可靠性,並為後續的測試、部署和交付提供了基礎。這個過程可以根據您的應用程序和項目的需求進行自定義。 ### Test "Test"步驟是確保應用程序或代碼在每次更改後都能保持高質量的關鍵部分之一。"Test"流程旨在自動化測試,包括單元測試、集成測試、功能測試以及性能和安全測試等,以確保代碼的可靠性、安全性和性能。以下是CI/CD流程中"Test"步驟的主要內容: * 單元測試: 單元測試是針對代碼中的單個功能、方法或模組的測試。它們旨在確保每個部分的行為符合預期。這些測試通常由開發人員編寫,並在代碼提交到版本控制系統之前運行。 * 集成測試: 集成測試驗證不同模組或部分之間的集成,確保它們可以正確協同工作。這些測試可以檢測到模組之間的交互問題。 * 功能測試: 功能測試確保應用程序的功能按照規範正確運作。這些測試模擬了最終用戶的操作,以確保應用程序在各種使用情境下都能正常工作。 * 性能測試: 性能測試評估應用程序在正常和高負載下的性能。這包括測試響應時間、併發使用者數、吞吐量等性能指標。 * 安全測試: 安全測試確保應用程序不容易受到常見的安全漏洞和攻擊(例如SQL注入、跨站腳本攻擊等)的影響。安全測試可以掃描代碼,模擬攻擊,以及評估身份驗證和授權機制。 * 自動化測試: CI/CD的目標之一是自動化測試。這意味著所有測試都應該能夠在不需要手動干預的情況下運行。這樣可以確保在每次更改時都能快速進行測試,並在出現問題時立即通知團隊。 * 測試報告: 測試過程應生成詳細的測試報告,以便團隊了解測試結果和問題。這些報告可以包括測試覆蓋率、錯誤日誌、性能指標等信息。 * 回饋和修復: 如果測試流程中發現了問題,則開發團隊應該儘快修復這些問題。修復後,測試過程應再次運行,以確保問題已解決。 * 持續集成: 測試是CI/CD流程中的一部分,通常與持續集成相結合。每次代碼提交到版本控制系統時,CI工具將自動觸發測試過程,這有助於及早發現和解決問題。 總之,CI/CD流程中的"Test"步驟是確保軟件質量和穩定性的關鍵部分,通過自動化測試來測試代碼的各個方面,並確保在部署新功能或更改時不會引入錯誤或性能問題。 #### 測試工具 * Karma = Test runner (testing environment):快速建構及執行 test code 的環境工具,常見的有: Karma / Jest / Chai * Jasmine = Assertion library (斷言庫):輔助 Test runner 對錯判定的工具,通常有很多好用的 method 幫助做比對,常見的有: Jasmine / Enzyme / Mocha * OWASP ZAP: Web應用程式 * SonarQube: 基於Java 開發的程式碼檢測以及品質管理平台,也提供了不少的服務像是:網頁化操作、支援非常多種程式語言的分析檢測、提供程式碼重複性、潛在 bug、測試覆蓋率等等相關報告、提供自動化分析並且結合主流的 CI 工具、提供程式碼改善建議、整合 JIRA、Mantis、LDAP、Fortify 等外部工具提供歷史紀錄以利於後續追蹤 ## CI/CD Tools ### drone 輕量小、各種git repository server docker runner docker k8s 其它 設定檔、pipeline : yml格式 ### circle SaaS、可自架server 、各種git repository 設定檔、pipeline : yml格式 ### GitLab實現CI/CD @SEANWEI ![](https://hackmd.io/_uploads/rJDiehMgT.png) Gitlab CI/CD 架構 #### Gitlab Server * Watcher: 監聽新 commit,Gitlab CI/CD 已於背後實作 * CI/CD configuration file: 定義執行腳本,預設為 .gitlab-ci.yml * Gitlab Runner: 負責執行腳本的的 instance (VM, docker…) * Gitlab API or 3rd party integration (optional) GitLab主要的服務是提供git版本控制系統,其CI/CD Pipeline功能簡單又實用,使用者只需要設定於專案根目錄下的「.gitlab-ci.yml」檔,便可以開始驅動各種Pipeline協助您完成自動化測試及部署。目前有提供GitLab CE(社群版)與 GitLab EE(企業版)兩種,使用者可以根據自己的需求選擇適合不同的方案。 ![](https://hackmd.io/_uploads/ry57BhMeT.png) #### 常用做法 1. CI/CD pipeline 過程中將最新程式 build 成 image 推到 docker hub 2. 通知 k8s 或 load balancer 從 docker hub pull 最新的 image 來完成更版 2.1. 為避免 runner 權限過大,有些公司會將部署 k8s 權限交由 ArgoCD 控管 ![](https://hackmd.io/_uploads/rkwyM6Gxa.png) Gitlab CI/CD 細節上還有很多參數可以用,設計的好壞也會影響部署速度,同時也提供 API 與程式或第三方整合,都等著你去發現 ## DevOps VS CI/CD @StanShih DevOps 是 Development 和 Operations 的組合,是一種方法論,是一組過程、方法與系統的統稱,用於促進應用開發、應用運維和質量保障(QA)部門之間的溝通、協作與整合。以期打破傳統開發和運營之間的壁壘和鴻溝。 ![](https://hackmd.io/_uploads/rkowxhfxa.png) DevOps 是一種重視 “軟件開發人員(Dev)” 和“IT 運維技術人員(Ops)”之間溝通合作的文化、運動或慣例。通過自動化 “軟件交付” 和“架構變更”的流程,來使得構建、測試、發佈軟件能夠更加地快捷、頻繁和可靠。具體來說,就是在軟件交付和部署過程中提高溝通與協作的效率,旨在更快、更可靠的的發佈更高質量的產品。 也就是說 DevOps 是一組過程和方法的統稱,並不指代某一特定的軟件工具或軟件工具組合。各種工具軟件或軟件組合可以實現 DevOps 的概念方法。其本質是一整套的方法論,而不是指某種或某些工具集合,與軟件開發中設計到的 OOP、AOP、IOC(或 DI)等類似,是一種理論或過程或方法的抽象或代稱. {%youtube _I94-tJlovg %} ## Jenkins vs GitLab CI/CD 之間的區別 @Danny ![](https://hackmd.io/_uploads/S1Z0ZnGlT.png) 藉助GitLab CI/CD,你可以完全控制分支和其他幾個方面來控制Git儲存庫,以確保程式碼免受突發威脅。但是,在Jenkins情況下,你能控制儲存庫,但範圍有限。它不允許完全控制分支和其他構面。 Jenkins是“內部託管”的,並且是“免費開放原始碼”,這是編碼人員偏愛它的原因。另一方面,Gitlab CI/CD是“自託管”和“免費”的,這就是開發人員更喜歡它的原因。 在GitLab CI/CD中,每個專案都有一個跟蹤器,該跟蹤器將跟蹤問題並執行程式碼審查以提高效率。在使用Jenkins工具時;它更改了支援集合,並簡化了安裝和配置過程。 。Jenkins 用於持續整合,而 GitLab CI/CD 用於程式碼協作和版本控制。在選擇最佳的用於 DevOps 測試的 CI/CD 工具時,除了突出的特性,你還應該檢視價格列表和內部熟練度。 ## 使用 GitLab + Jenkins 實現持續整合(CI)環境 1.開發者將新版本程式碼 push 到 GitLab 遠端倉庫上; 2.隨後 GitLab 會觸發 Jenkins 來進行拉取到本地(通過 Web Hook 或定時檢測) 3.最後 Jenkins 會根據事先設定好的指令碼進行 Build。 https://tw511.com/a/01/37663.html ## CI/CD ![](https://hackmd.io/_uploads/ryapJhGxp.png) * The ***operate*** step of CI/CD refers to the process of deploying the application to a server automatically. * ***Monitoring*** CI/CD operations is key for optimizing overall application performance 1. Datadog 2. Splunk 3. Jenkins 4. Tekton @ShenKuo ## GitHub Action GitHub Actions 是由 GitHub 提供的服務,用於在 GitHub 建置、測試、封裝、發佈或部署任何專案。並可藉此建置端對端 (end-to-end) CI/CD 功能,即持續整合/持續交付 (微軟譯為持續傳遞) 服務。 ### 基本元素 要了解 Github Actions 的基本概念,有幾個元素(或是術語)是必須要知道的,範圍由大至小分別為: Workflow -> Job -> Step -> Action Workflow : CI/CD 一次要運行的整個過程,就稱作 Workflow,一個 Workflow 裡會涵蓋多個 Job、Step、 Action。 Job : 意義跟翻成中文差不多,代表「任務」。一個 Workflow 由多個 Job 組成,這也意謂著一個 Workflow 可以完成多個任務。 Step : 代表一個個「步驟」,一個 Job 由多個 Step 組成,意謂著一個 Job 是一個步驟一個步驟來完成的。 Action : 「命令」或「動作」,每個 Step 可以依序執行多個命令(動作)。 ## 參考文獻 - https://www.readfog.com/a/1632555420399800320 - https://then.tw/github-actions/ - https://medium.com/starbugs/%E5%AF%A6%E4%BD%9C%E9%96%8B%E6%BA%90%E5%B0%8F%E5%B7%A5%E5%85%B7-%E8%88%87-github-actions-%E7%9A%84%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%9B%B8%E9%81%87-3dd2d70eeb - https://linyencheng.github.io/2022/05/30/devops-gitlab-ci-and-gitlab-runner/ - https://ithelp.ithome.com.tw/articles/10238855 - https://ithelp.ithome.com.tw/articles/10241701 - https://docs.gitlab.com/ee/ci/variables/ - https://enzochang.com/cicd-introduction/