Gitea Actions 工作流入门指南(实战三)

📝 前言

这是 DevOps 专题的第五篇,回顾一下前几篇的内容:

这一篇我们就正式开始介绍如何使用 Gitea Actions 来完成 CI/CD 工作流。

🧭 背景介绍

随着 DevOps 自动化的普及,CI/CD 成为现代软件开发的标配。

对于使用自托管 Git 服务的团队来说,如何像在 GitHub 中使用 Actions 一样,在 Gitea 中实现类似的工作流自动化,是一个值得关注的问题。

幸运的是,Gitea 从 1.19 开始引入了原生 CI 功能 —— Gitea Actions,功能与 GitHub Actions 高度兼容,支持 YAML 工作流文件和 Docker 容器运行环境,是 GitHub Actions 的极佳替代方案。

🔍 使用场景

  • 企业或团队出于安全或合规考虑使用自建 Git 服务。
  • 替代 GitHub Actions,实现私有化部署的 CI/CD。
  • 在内网环境中自动构建、测试、部署应用程序。

📋 前提条件

在开始之前,请确保你具备以下环境准备:

🧩 Gitea Actions 工作流结构解析

Gitea Actions 的工作流文件存放在仓库路径:.gitea/workflows/ 中,以 .yaml或.yml 结尾。

PS:区别于 Github Action,需要放到 .gitea 目录。

以下为一个简单的工作流示例,我们将通过该示例来讲解工作流的结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
name: 工作流名称

on:
push:
branches:
- main

jobs:
build:
runs-on: host
steps:
- name: 步骤说明
run: echo "Hello World"

结构说明:

  • name:工作流名称,工作流是自动化任务的顶层单元,由一个或多个 Jobs 组成,通常由代码仓库中的事件(如 pushpull_request)触发。
  • on.push.branches:监听push到指定分支的事件,当触发该事件时,则会自动执行工作流,如示例中是监听main分支的push事件。
  • jobs:任务集合,Jobs 是 Workflow 中的执行单元,支持并行或串行执行(Gitea 并行好像还不完善),每个 Job 代表一个独立的任务(如构建、测试),也即是说每个不同的 Job 工作空间是隔离的。
  • jobs.build:Job 名称,Job 是 Jobs 集合中的具体任务,由多个 Steps 组成,在同一个运行环境中顺序执行。
  • jobs.build.runs-on:指定运行环境,对应着runner上的标签,该标签也可以配置为容器运行。
  • jobs.build.steps:一组 step 组合,可执行多个步骤。
  • jobs.build.steps.name:step 名称,Step 是 Job 中的最小执行单元,代表一个具体的操作(如运行命令、调用 Action)。
  • jobs.build.steps.run:执行具体的 shell 命令。

层级结构:Workflow → Jobs → Job → Steps → step

  • 一个 Workflow 包含多个 Jobs。
  • 一个 Job 包含多个 Steps。
  • 一个 Steps 包含多个 Step。

总体介绍一下,这个工作流的意思就是当监听到代码pushmain分支事件时,自动开始在host宿主机进行构建,并在控制台输出Hello World

下面我们再来一个实际的场景案例,该案例为 Python 后端接口项目。

🚀 详细步骤

1️⃣ 创建 Gitea 仓库

登录 Gitea 实例,点击右侧创建项目,如下图所示:

填写仓库名称,其他保持默认,再点击最下面的创建仓库即可。

2️⃣ 下载项目

创建完项目根据提示的地址,下载项目到本地:

1
git clone http://git.luhome.com/lusyoe/python-workflow-demo.git

3️⃣ 创建 python 代码

进入下载的空仓库目录,创建python代码文件:

1
2
3
4
5
# 进入仓库目录
cd python-workflow-demo

# 创建代码文件
vim main.py

代码文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from http.server import BaseHTTPRequestHandler, HTTPServer

class HelloHandler(BaseHTTPRequestHandler):
def do_GET(self):
# 设置响应状态码为 200
self.send_response(200)
# 设置响应头
self.send_header("Content-type", "text/plain")
self.end_headers()
# 响应内容
self.wfile.write(b"Hello, World")

if __name__ == "__main__":
server_address = ('', 8000) # 监听所有地址的8000端口
httpd = HTTPServer(server_address, HelloHandler)
print("Serving on port 8000...")
httpd.serve_forever()

4️⃣ 创建 Dockerfile

如果我们需要将代码部署到服务器,使用Docker镜像部署无疑是较好的选择,可以屏蔽环境依赖,达到一次构建处处运行的目的。

构建Docker镜像就需要依赖Dockerfile文件,关于Dockerfile的语法等后面有时间再介绍,我们先直接使用以下模板即可。

继续在项目根目录创建并编辑 Dockerfile 文件:

vim Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 使用官方 Python 运行时作为基础镜像
FROM python:3.12-slim

# 设置工作目录
WORKDIR /app

# 复制本地代码到容器中
COPY main.py .

# 暴露端口
EXPOSE 8000

# 设置启动命令
CMD ["python", "main.py"]

5️⃣ 创建工作流文件

上面已经介绍过 Gitea 是会自动解析项目根目录的.gitea/workflows/*.yaml文件,并生成工作流。

因此我们也需要创建出该目录及文件,操作如下:

1
2
3
4
5
# 创建并进入工作流目录
mkdir -p .gitea/workflows/ && cd .gitea/workflows/

# 创建工作流文件
vim build.yaml

文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
name: Build and Deploy Python Demo

on:
push:
branches: [ main ]
env:
# node 环境变量
PATH: /opt/node/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
REGISTRY: <你的镜像仓库地址>
IMAGE_NAME: <你的镜像仓库项目>/python-workflow-demo
CONTAINER_NAME: python-workflow-demo

jobs:
# 构建 Job
build:
runs-on: host
outputs: # 声明作业的输出变量,方便在其他 Job 引用
datetime: ${{ steps.datetime.outputs.datetime }}
steps:
# 下载仓库源码,依赖node环境,因此构建服务器本地需要下载安装node并设置环境变量
- name: Checkout repository
uses: actions/checkout@v4

# 登录镜像仓库,方便后续上传镜像
- name: Login to Docker Registry
uses: actions/docker-login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: admin
# 这里也可以通过 secrets 传入,后面再介绍
password: <你镜像仓库密码>

# 获取时间戳,用于设置镜像 TAG 版本
- name: Get datetime
id: datetime
run: |
echo "datetime=$(date '+%Y-%m-%d-%H-%M-%S')" >> $GITHUB_OUTPUT

# 构建并上传镜像
- name: Build and push Docker image
uses: actions/docker-build-push-action@v5
with:
context: .
platforms: linux/amd64
file: Dockerfile
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.datetime.outputs.datetime }}
# 部署 Job
deploy:
runs-on: host
needs: build
steps:
# 直接在构建服务器本地部署 Docker 容器,也可以使用ssh-action到远程部署
- name: Deploy
run: |
DATETIME='${{ needs.build.outputs.datetime }}'
docker stop ${{ env.CONTAINER_NAME }} || true
docker rm ${{ env.CONTAINER_NAME }} || true
docker run -d --name ${{ env.CONTAINER_NAME }} -p 8000:8000 ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${DATETIME}

详细介绍都已经有在注释中说明,若有疑问可在评论区交流~

PS:另外由于国内环境原因,可能 github 的 actions 并不能正常下载,可离线下载并上传到自己的Gitea仓库,然后uses直接填自己仓库的完整地址即可,如:

1
http://<你的gitea实例地址>/actions/checkout@v4

6️⃣ 提交代码自动构建部署

回到项目根目录,提交代码到远程仓库:

1
2
3
4
cd ../..
git add .
git commit -m "init"
git push

登录 Gitea,进入项目的Actions中,可以看到已经开始自动执行工作流了。

当部署完成后,通过浏览器访问部署服务器IP:8000端口,能看到 Hello,World 即为部署成功。

✅ 总结

最后总结一下,通过 .gitea/workflows/*.yml,你可以在 Gitea 项目中快速定义并运行自动化任务。

Gitea Actions 基本都兼容 GitHub Actions 的语法,学习成本低,同时也适合私有部署场景。

后面会再介绍更多关于 Gitea Actions 的用法,欢迎持续关注~