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

前言

Gitea 是一個用於代碼託管的輕量級單體程序,它能與現有的經典應用集成,諸如代碼分析工具 SonarQube、持續集成工具 Drone、Jenkins 以及用於工單管理的客戶端插件(VSCode、Jenkins IDE)。 不久之後,Gitea 也將迎來自身集成的一體化 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 流水線。

插件詳情://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 設置

conf/app.ini 中添加 ALLOWED_HOST_LIST = * 允許從外部服務器觸發 Gitea webhook。

[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 地址,如 //gitea.com
  • 勾選 Manage hooks 並選擇訪問令牌。這將允許 Jenkins 使用您選擇的 Gitea 帳戶自動配置 Gitea Webhook,當代碼提交到 Gitea 時,Gitea 通過 Webhook (//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。

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