Gitea 與 Jenkins 的整合實踐,打造你的專屬 CI/CD 系統

語言: CN / TW / HK

前言

Gitea 是一個用於程式碼託管的輕量級單體程式,它能與現有的經典應用整合,諸如程式碼分析工具 SonarQube、持續整合工具 Drone、Jenkins 以及用於工單管理的客戶端外掛(VSCode、Jenkins IDE)。 不久之後,Gitea 也會相容 GitHub Actions 使得 CI/CD 流程更加簡單。

今天要介紹的是 Gitea 與 Jenkins CI/CD 的整合。

關於 Jenkins

Jenkins 是一款開源的、提供友好操作介面的持續整合(CI)工具,在國內外都有眾多的使用者。Jenkins 具有以下優點:

  • 介面友好
  • 外掛豐富
  • 可程式設計的 API
  • 歷史悠久、社群活躍

因此 Jenkins 也被眾多的企業或者組織用來構建自己的 CI/CD 系統。

然而,Jenkins 本身並不具備原始碼管理的能力,對於一個完整的 CI/CD 系統來講,必須要從原始碼管理系統開始。所以,本文將介紹如何利用 Gitea 和 Jenkins 來構建一個完整的 CI/CD 系統。

關於 Jenkins 的 Gitea 外掛

Jenkins 支援從通用 Git 伺服器拉取程式碼,無需安裝額外的外掛即可配合 Gitea 使用。用於 Jenkins 的 Gitea 外掛作用在於將 Jenkins CI/CD 許可權直接賦予 Gitea 伺服器上被授權的組織或個人,使用者無需單獨為每一個倉庫配置 Jenkins 觸發器即可享受 CI/CD 功能。

當用戶在倉庫中建立 Jenkinsfile 時,Jenkins 能夠自動掃描到該倉庫並啟動 CI/CD 流水線。

外掛詳情:https://plugins.jenkins.io/gitea/

流程概覽

本次整合實踐主要包含以下內容

  • Gitea Plugin 外掛的介紹和配置
  • Gitea + Jenkins 的 CI/CD 環境搭建
  • 利用 Gitea 的 Webhook 功能,從 Gitea 側觸發 Jenkins Pipeline

Gitea

  1. 在 Gitea 註冊使用者 Jenkins,同時為使用者 Jenkins 新增 API Access Token,用於 Jenkins 從 Gitea 拉取程式碼
  2. 在 Gitea 中建立組織 GiteaTeam,並且將 Jenkins 使用者新增為組織管理員
  3. 在 GiteaTeam 組織中建立程式碼倉庫 JenkinsExample
  4. 修改 Gitea 伺服器的 Webhook 設定

Jenkins

  1. 登入 Jenkins 管理面板,安裝外掛:Gitea
  2. 開啟 Manage Credentials 新增 Gitea 訪問令牌,用於從 Gitea 拉取程式碼、通過 API 安裝 Webhook
  3. 開啟 Configure System 配置 Gitea Server 外掛,填寫 Gitea 伺服器地址和 Mange Hooks 令牌(選用上一步填寫的 Credentials)
  4. 整合演示 JenkinsExample

Gitea + Jenkins 的 Docker Compose 配置示例

如果您還沒有搭建以上環境,我們提供了一個 docker-compose.yml 模板幫助您快速啟動,模板內容附在本文最後。

Gitea 與 Jenkins 的整合實踐

生成 Gitea 訪問令牌

在本示例中,我們為 Jenkins 單獨建立了一個名為 Jenkins 的 Gitea 使用者賬號,便於 Jenkins 使用令牌訪問 Gitea 伺服器。

為 Jenkins 授予 Gitea 專案的訪問許可權

在本示例中,我們在 Gitea 伺服器建立了一個組織 GiteaTeam 用於存放專案原始碼。同時,將 Jenkins 賬號加入 GiteaTeam 的管理員使用者組,便於 Jenkins 直接訪問當前專案的程式碼倉庫、API、Webhook。

修改 Gitea 伺服器的 Webhook 白名單

出於安全考慮,您通過 Gitea Webhook 觸發外部伺服器的響應前需要設定 webhook.ALLOWED_HOST_LIST 白名單來控制 Webhook 的目的地址。具體資訊參考文件 Webhook

修改配置時,開啟 conf/app.ini,新增 ALLOWED_HOST_LIST = *[webhook] 欄目中,並重啟 Gitea 伺服器。例如:

ini [webhook] ALLOWED_HOST_LIST = *

安裝 Gitea Plugin

在 Jenkins 依次開啟 系統管理 - 外掛管理,在 可選外掛 中搜索並安裝 Gitea

在 Jenkins 中新增 Gitea 訪問令牌

開啟 Manage Credentials 新增 Gitea 訪問令牌,用於從 Gitea 拉取程式碼、通過 API 安裝 Webhook。

  • Kind: 選擇 Gitea Personal Access Token
  • Scope: 選擇 Global
  • Token: 填寫從 Gitea 申請的訪問令牌

在 Jenkins 中配置 Gitea Server

Gitea Plugin 安裝完成後,在 Jenkins 依次開啟 系統管理 - 系統配置,找到 Gitea Server 並填寫:

  • Name: 任意填寫一個名稱
  • Server URL: 填寫 Gitea 伺服器的 HTTP 地址,如 https://gitea.com
  • 勾選 Manage hooks 並選擇訪問令牌。這將允許 Jenkins 使用您選擇的 Gitea 帳戶自動配置 Gitea Webhook,當代碼提交到 Gitea 時,Gitea 通過 Webhook (http://JENINS_URL/gitea-webhook/post) 觸發 Jenkins CI。

在 Jenkins 中建立 Organization Folder

Organization Folder 任務支援從 Gitea 伺服器掃描並自動新增組織或使用者目錄下的所有程式碼倉庫。當代碼倉庫中包含 Jenkinsfile 時會自動將該倉庫加入流水線佇列。在這種模式下,該組織下的程式碼倉庫無需單獨配置 Webhook 便可以自動與 Jenkins CI 整合。

配置 Repository Sources

開啟剛才建立的 Organization Folder。在 Projects - Repository Sources 中新增 Gitea Organization 並填寫:

  • Server: 選擇一個 Gitea Server
  • Owner: 與 Jenkins 整合的 Gitea 組織或個人目錄
  • Credentials: 選擇一個用於訪問 Gitea 的 Jenkins 賬號訪問令牌(應該擁有 Owner 的管理許可權)

稍後,Jenkins 就會開始掃描 Gitea 伺服器上的 GiteaTeam 組織,在 Scan Gitea Organization Log 呈現出掃描結果:

整合演示 JenkinsExample

在上面的整合配置中,我們為 Gitea 伺服器上的 GiteaTeam 組織集成了 Jenkins CI 能力。於是,當用戶在 GiteaTeam 組織中建立包含 Jenkinsfile 的程式碼倉庫時, Jenkins CI 也將自動啟動,為 Gitea 配置 Webhook。當用戶再次提交程式碼到 Gitea 伺服器時,Jenkins 就能被 Gitea Webhook 觸發構建過程。

建立 JenkinsExample 專案

Jenkinsfile 示例

JenkinsExample 專案中僅包含一個有效的 Jenkinsfile 示例檔案,用於演示 Jenkins CI 與 Gitea 的整合。

pipeline { agent any stages { stage('Build') { steps { sh 'echo build' } } stage('Test'){ steps { sh 'echo test' } } stage('Deploy') { steps { sh 'echo publish' } } } }

檢查 Gitea Plugin 建立的 Webhook

當我們的組織與 Jenkins 整合之後,Gitea Plugin 外掛自動為新建的 Jenkins 專案建立 Webhook。(前提是在 Gitea Plugin 中勾選 Manage hook)

檢查 Gitea Plugin 自動為 Gitea 建立的 Webhook:

提交程式碼更改並檢視 Jenkins CI 流程

  1. 在 Gitea 的提交列表中,我們可以觀察到當前程式碼提交的構建情況,黃色的 ● 表示正在進行構建任務,綠色的 ✔ 表示已經完成的構建任務。

  1. 點選上面的 ●、✔、× 符號可以進入 Jenkins Pipeline 檢視任務詳情情況。

Gitea + Jenkins 的 Docker Compose 配置示例

最新的 Docker Enginine 已經集成了 docker compose 命令,您可以使用 docker compose up -d 一鍵啟動 Gitea 和 Jenkins。

```yaml version: "3"

volumes: jenkins_home:

services: server: image: gitea/gitea:latest container_name: gitea environment: - USER_UID=1000 - USER_GID=1000 restart: always volumes: - ./data:/data - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro ports: - 3000:3000

jenkins: container_name: jenkins image: jenkins/jenkins:lts-jdk11 restart: on-failure privileged: true volumes: - jenkins_home:/var/jenkins_home - /var/run/docker.sock:/var/run/docker.sock - /etc/localtime:/etc/localtime:ro ports: - 8080:8080 - 50000:50000 ```