Skip to content

Commit 42232c1

Browse files
committed
refactor(ci): 重构 Docker 构建流程为矩阵构建模式
- 引入 build-matrix.json 统一管理多版本构建配置 - 将单一 Dockerfile 拆分为版本化目录结构(nginx-x.x.x/mod-x.x.x/Dockerfile) - 实现构建矩阵自动化,支持并行构建多个 nginx 和 modsecurity 版本组合 - 添加镜像存在性检查,避免重复构建已存在的 tag - 支持手动触发时强制重建所有镜像 - 简化 update.sh 脚本,自动从模板生成新版本 Dockerfile 并更新构建矩阵 - 移除 versions.env、mainline_version、stable_version 等冗余配置文件 - 优化 tag 生成逻辑,根据角色(mainline/stable)自动添加对应标签
1 parent 4ba5887 commit 42232c1

8 files changed

Lines changed: 202 additions & 381 deletions

File tree

.github/workflows/docker-image.yml

Lines changed: 110 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -2,120 +2,127 @@ name: Docker Image CI
22

33
on:
44
push:
5-
branches: [ "master" ]
5+
branches: ["master"]
66
paths:
7-
- 'Dockerfile.latest'
8-
- 'versions.env'
9-
- 'stable_version'
10-
- 'mainline_version'
11-
tags:
12-
- 'v*'
13-
workflow_dispatch: # 添加手动触发选项
7+
- "build-matrix.json"
8+
- "nginx-*/mod-*/Dockerfile"
9+
workflow_dispatch:
10+
inputs:
11+
force_rebuild:
12+
description: "强制重建所有镜像(忽略已存在的 tag)"
13+
required: false
14+
default: false
15+
type: boolean
1416

1517
permissions:
1618
contents: read
1719
packages: write
1820

1921
jobs:
22+
prepare:
23+
runs-on: ubuntu-latest
24+
outputs:
25+
matrix: ${{ steps.set-matrix.outputs.matrix }}
26+
steps:
27+
- name: Checkout code
28+
uses: actions/checkout@v4
29+
30+
- name: Generate build matrix
31+
id: set-matrix
32+
run: |
33+
MATRIX=$(jq -c '{include: .builds}' build-matrix.json)
34+
echo "matrix=${MATRIX}" >> $GITHUB_OUTPUT
35+
echo "构建矩阵: ${MATRIX}"
36+
2037
build-and-push:
38+
needs: prepare
2139
runs-on: ubuntu-latest
40+
strategy:
41+
matrix: ${{ fromJson(needs.prepare.outputs.matrix) }}
42+
fail-fast: false
2243

23-
if: github.event_name == 'push' && github.ref_type == 'branch' || github.event_name == 'workflow_dispatch'
24-
2544
steps:
26-
- name: Checkout code
27-
uses: actions/checkout@v4
28-
29-
- name: Set up Docker Buildx
30-
uses: docker/setup-buildx-action@v3
31-
32-
- name: Login to Docker Hub
33-
uses: docker/login-action@v3
34-
with:
35-
username: ${{ secrets.DOCKERHUB_USERNAME }}
36-
password: ${{ secrets.DOCKERHUB_TOKEN }}
37-
38-
- name: Login to GitHub Container Registry
39-
uses: docker/login-action@v3
40-
with:
41-
registry: ghcr.io
42-
username: ${{ github.repository_owner }}
43-
password: ${{ secrets.GITHUB_TOKEN }}
44-
45-
- name: Set version variables
46-
id: versions
47-
run: |
48-
# 从 versions.env 文件中提取版本信息
49-
if [ -f "versions.env" ]; then
50-
source versions.env
51-
echo "nginx_version=${NGINX_VERSION}" >> $GITHUB_OUTPUT
52-
echo "modsec_version=${MODSECURITY_VERSION}" >> $GITHUB_OUTPUT
53-
echo "modsec_version_clean=${MODSECURITY_VERSION#v}" >> $GITHUB_OUTPUT
54-
echo "modsec_nginx_version=${MODSECURITY_NGINX_VERSION}" >> $GITHUB_OUTPUT
55-
echo "build_date=${BUILD_DATE}" >> $GITHUB_OUTPUT
56-
57-
echo "使用 versions.env 中的版本信息:"
58-
echo "Nginx: ${NGINX_VERSION}"
59-
echo "ModSecurity: ${MODSECURITY_VERSION}"
60-
echo "ModSecurity-nginx: ${MODSECURITY_NGINX_VERSION}"
61-
else
62-
echo "versions.env 文件不存在,请确保它在仓库中并包含正确的版本信息。"
63-
exit 1
64-
fi
65-
66-
# 检查是否为最新主线版本
67-
if [ -f "mainline_version" ]; then
68-
MAINLINE_VERSION=$(cat mainline_version)
69-
if [ "${NGINX_VERSION}" == "${MAINLINE_VERSION}" ]; then
70-
echo "is_mainline=true" >> $GITHUB_OUTPUT
71-
echo "当前版本 ${NGINX_VERSION} 是最新主线版本,将使用 latest 标签"
45+
- name: Checkout code
46+
uses: actions/checkout@v4
47+
48+
- name: Set version variables
49+
id: vars
50+
run: |
51+
MODSEC_CLEAN="${{ matrix.modsecurity }}"
52+
MODSEC_CLEAN="${MODSEC_CLEAN#v}"
53+
echo "version_tag=${{ matrix.nginx }}-${MODSEC_CLEAN}" >> $GITHUB_OUTPUT
54+
echo "modsec_clean=${MODSEC_CLEAN}" >> $GITHUB_OUTPUT
55+
56+
- name: Check if image already exists
57+
id: check
58+
if: ${{ github.event.inputs.force_rebuild != 'true' }}
59+
run: |
60+
TAG="${{ steps.vars.outputs.version_tag }}"
61+
if docker manifest inspect "e1saps/nginx-modsecurity:${TAG}" > /dev/null 2>&1; then
62+
echo "skip=true" >> $GITHUB_OUTPUT
63+
echo "镜像 e1saps/nginx-modsecurity:${TAG} 已存在,跳过构建"
7264
else
73-
echo "is_mainline=false" >> $GITHUB_OUTPUT
74-
echo "当前版本 ${NGINX_VERSION} 不是最新主线版本 ${MAINLINE_VERSION},不会使用 latest 标签"
65+
echo "skip=false" >> $GITHUB_OUTPUT
66+
echo "镜像 e1saps/nginx-modsecurity:${TAG} 不存在,开始构建"
7567
fi
76-
else
77-
echo "mainline_version 文件不存在,默认当前版本不是最新主线版本"
78-
echo "is_mainline=false" >> $GITHUB_OUTPUT
79-
fi
80-
81-
# 检查是否为最新稳定版本
82-
if [ -f "stable_version" ]; then
83-
STABLE_VERSION=$(cat stable_version)
84-
if [ "${NGINX_VERSION}" == "${STABLE_VERSION}" ]; then
85-
echo "is_stable=true" >> $GITHUB_OUTPUT
86-
echo "当前版本 ${NGINX_VERSION} 是最新稳定版本,将使用 stable 标签"
87-
else
88-
echo "is_stable=false" >> $GITHUB_OUTPUT
89-
echo "当前版本 ${NGINX_VERSION} 不是最新稳定版本 ${STABLE_VERSION},不会使用 stable 标签"
68+
69+
- name: Set up Docker Buildx
70+
if: steps.check.outputs.skip != 'true'
71+
uses: docker/setup-buildx-action@v3
72+
73+
- name: Login to Docker Hub
74+
if: steps.check.outputs.skip != 'true'
75+
uses: docker/login-action@v3
76+
with:
77+
username: ${{ secrets.DOCKERHUB_USERNAME }}
78+
password: ${{ secrets.DOCKERHUB_TOKEN }}
79+
80+
- name: Login to GitHub Container Registry
81+
if: steps.check.outputs.skip != 'true'
82+
uses: docker/login-action@v3
83+
with:
84+
registry: ghcr.io
85+
username: ${{ github.repository_owner }}
86+
password: ${{ secrets.GITHUB_TOKEN }}
87+
88+
- name: Generate tags
89+
if: steps.check.outputs.skip != 'true'
90+
id: tags
91+
run: |
92+
TAGS=""
93+
VERSION_TAG="${{ steps.vars.outputs.version_tag }}"
94+
NGINX="${{ matrix.nginx }}"
95+
ROLE="${{ matrix.role }}"
96+
97+
# 版本 tag(始终添加)
98+
TAGS="e1saps/nginx-modsecurity:${NGINX}"
99+
TAGS="${TAGS},e1saps/nginx-modsecurity:${VERSION_TAG}"
100+
TAGS="${TAGS},ghcr.io/${{ github.repository }}:${NGINX}"
101+
TAGS="${TAGS},ghcr.io/${{ github.repository }}:${VERSION_TAG}"
102+
103+
# 角色 tag
104+
if [ "${ROLE}" = "mainline" ]; then
105+
TAGS="${TAGS},e1saps/nginx-modsecurity:latest"
106+
TAGS="${TAGS},e1saps/nginx-modsecurity:mainline"
107+
TAGS="${TAGS},ghcr.io/${{ github.repository }}:latest"
108+
TAGS="${TAGS},ghcr.io/${{ github.repository }}:mainline"
109+
elif [ "${ROLE}" = "stable" ]; then
110+
TAGS="${TAGS},e1saps/nginx-modsecurity:stable"
111+
TAGS="${TAGS},ghcr.io/${{ github.repository }}:stable"
90112
fi
91-
else
92-
echo "stable_version 文件不存在,默认当前版本不是最新稳定版本"
93-
echo "is_stable=false" >> $GITHUB_OUTPUT
94-
fi
95-
96-
- name: Extract metadata for Docker
97-
id: meta
98-
uses: docker/metadata-action@v5
99-
with:
100-
images: |
101-
e1saps/nginx-modsecurity
102-
ghcr.io/${{ github.repository }}
103-
tags: |
104-
type=raw,value=latest,enable=${{ steps.versions.outputs.is_mainline == 'true' }}
105-
type=raw,value=mainline,enable=${{ steps.versions.outputs.is_mainline == 'true' }}
106-
type=raw,value=stable,enable=${{ steps.versions.outputs.is_stable == 'true' }}
107-
type=raw,value=${{ steps.versions.outputs.nginx_version }}
108-
type=raw,value=${{ steps.versions.outputs.nginx_version }}-${{ steps.versions.outputs.modsec_version_clean }}
109-
type=ref,event=tag
110-
type=sha,format=short
111-
112-
- name: Build and push
113-
uses: docker/build-push-action@v5
114-
with:
115-
context: .
116-
file: ./Dockerfile.latest
117-
push: true
118-
tags: ${{ steps.meta.outputs.tags }}
119-
labels: ${{ steps.meta.outputs.labels }}
120-
build-args: |
121-
VERSION=${{ github.ref_type == 'tag' && github.ref_name || github.sha }}
113+
114+
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
115+
echo "生成的 tags: ${TAGS}"
116+
117+
- name: Build and push
118+
if: steps.check.outputs.skip != 'true'
119+
uses: docker/build-push-action@v5
120+
with:
121+
context: .
122+
file: ${{ matrix.dockerfile }}
123+
push: true
124+
tags: ${{ steps.tags.outputs.tags }}
125+
labels: |
126+
org.opencontainers.image.title=nginx-modsecurity
127+
org.opencontainers.image.description=Nginx ${{ matrix.nginx }} with ModSecurity ${{ matrix.modsecurity }}
128+
org.opencontainers.image.version=${{ steps.vars.outputs.version_tag }}

Dockerfile.latest

Lines changed: 0 additions & 95 deletions
This file was deleted.

0 commit comments

Comments
 (0)