refactor: 将部署和删除功能分离到独立的 workflow 文件
- 创建 docker-build.yml:专门负责构建和推送 Docker 镜像 - 创建 docker-delete.yml:专门负责删除 Docker 镜像标签 - 简化 docker-build.yml,移除删除逻辑 - 更新文档,说明两个独立的 workflow 文件及其职责
This commit is contained in:
@@ -4,7 +4,6 @@ on:
|
|||||||
release:
|
release:
|
||||||
types:
|
types:
|
||||||
- published # 当通过 GitHub Releases 页面创建 release 时触发
|
- published # 当通过 GitHub Releases 页面创建 release 时触发
|
||||||
- deleted # 当删除 release 时触发
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-and-push:
|
build-and-push:
|
||||||
@@ -12,14 +11,11 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
if: github.event.action == 'published'
|
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.release.tag_name }} # 使用 release 对应的 tag
|
ref: ${{ github.event.release.tag_name }} # 使用 release 对应的 tag
|
||||||
|
|
||||||
# 构建和推送镜像(仅在发布 release 时)
|
|
||||||
- name: Extract version from release
|
- name: Extract version from release
|
||||||
if: github.event.action == 'published'
|
|
||||||
id: extract_version
|
id: extract_version
|
||||||
run: |
|
run: |
|
||||||
# 从 release tag 中提取版本号(例如 v1.0.0 -> 1.0.0)
|
# 从 release tag 中提取版本号(例如 v1.0.0 -> 1.0.0)
|
||||||
@@ -41,7 +37,6 @@ jobs:
|
|||||||
echo "Full tag: $TAG_NAME"
|
echo "Full tag: $TAG_NAME"
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
if: github.event.action == 'published'
|
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
with:
|
with:
|
||||||
# 启用多架构构建支持
|
# 启用多架构构建支持
|
||||||
@@ -54,7 +49,6 @@ jobs:
|
|||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
if: github.event.action == 'published'
|
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
@@ -71,80 +65,3 @@ jobs:
|
|||||||
GITHUB_REPO_URL=https://github.com/WrBug/PolyHermes
|
GITHUB_REPO_URL=https://github.com/WrBug/PolyHermes
|
||||||
cache-from: type=registry,ref=wrbug/polyhermes:latest
|
cache-from: type=registry,ref=wrbug/polyhermes:latest
|
||||||
cache-to: type=inline
|
cache-to: type=inline
|
||||||
|
|
||||||
# 删除镜像(仅在删除 release 时)
|
|
||||||
- name: Delete Docker image (when release is deleted)
|
|
||||||
if: github.event.action == 'deleted'
|
|
||||||
run: |
|
|
||||||
TAG_NAME="${{ github.event.release.tag_name }}"
|
|
||||||
|
|
||||||
# 验证版本号格式:v数字.数字.数字[-后缀](精准匹配)
|
|
||||||
if [[ ! "$TAG_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then
|
|
||||||
echo "警告: 版本号格式不正确 ($TAG_NAME),应为 v数字.数字.数字 或 v数字.数字.数字-后缀 (例如: v1.0.0, v1.0.0-beta)"
|
|
||||||
echo "跳过删除操作"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
IMAGE_NAME="wrbug/polyhermes"
|
|
||||||
DOCKER_USERNAME="${{ secrets.DOCKER_USERNAME }}"
|
|
||||||
DOCKER_PASSWORD="${{ secrets.DOCKER_PASSWORD }}"
|
|
||||||
|
|
||||||
echo "正在删除 Docker 镜像: ${IMAGE_NAME}:${TAG_NAME}"
|
|
||||||
|
|
||||||
# 方法 1: 尝试使用 JWT Token 认证(推荐,适用于 Access Token)
|
|
||||||
# 获取 JWT Token
|
|
||||||
echo "正在获取 Docker Hub JWT Token..."
|
|
||||||
TOKEN_RESPONSE=$(curl -s -X POST \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "{\"username\": \"${DOCKER_USERNAME}\", \"password\": \"${DOCKER_PASSWORD}\"}" \
|
|
||||||
"https://hub.docker.com/v2/users/login/")
|
|
||||||
|
|
||||||
# 提取 Token(支持多种格式)
|
|
||||||
TOKEN=$(echo "$TOKEN_RESPONSE" | grep -oE '"token":"[^"]*"' | head -1 | cut -d'"' -f4)
|
|
||||||
|
|
||||||
if [ -z "$TOKEN" ]; then
|
|
||||||
# 尝试另一种提取方式
|
|
||||||
TOKEN=$(echo "$TOKEN_RESPONSE" | python3 -c "import sys, json; print(json.load(sys.stdin).get('token', ''))" 2>/dev/null || echo "")
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$TOKEN" ] && [ "$TOKEN" != "null" ]; then
|
|
||||||
echo "✅ 成功获取 JWT Token,使用 JWT Token 认证"
|
|
||||||
# 使用 JWT Token 删除镜像标签
|
|
||||||
RESPONSE=$(curl -s -w "\n%{http_code}" -X DELETE \
|
|
||||||
-H "Authorization: JWT ${TOKEN}" \
|
|
||||||
"https://hub.docker.com/v2/repositories/${IMAGE_NAME}/tags/${TAG_NAME}/")
|
|
||||||
else
|
|
||||||
echo "⚠️ JWT Token 获取失败,尝试使用 Basic Auth"
|
|
||||||
echo " 如果继续失败,请检查 DOCKER_USERNAME 和 DOCKER_PASSWORD 是否正确"
|
|
||||||
# 方法 2: 使用 Basic Auth(适用于密码)
|
|
||||||
RESPONSE=$(curl -s -w "\n%{http_code}" -X DELETE \
|
|
||||||
-u "${DOCKER_USERNAME}:${DOCKER_PASSWORD}" \
|
|
||||||
"https://hub.docker.com/v2/repositories/${IMAGE_NAME}/tags/${TAG_NAME}/")
|
|
||||||
fi
|
|
||||||
|
|
||||||
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
||||||
BODY=$(echo "$RESPONSE" | head -n-1)
|
|
||||||
|
|
||||||
if [ "$HTTP_CODE" = "204" ]; then
|
|
||||||
echo "✅ 成功删除 Docker 镜像标签: ${IMAGE_NAME}:${TAG_NAME}"
|
|
||||||
elif [ "$HTTP_CODE" = "404" ]; then
|
|
||||||
echo "⚠️ 镜像标签不存在: ${IMAGE_NAME}:${TAG_NAME},可能已被删除或不存在"
|
|
||||||
elif [ "$HTTP_CODE" = "401" ]; then
|
|
||||||
echo "❌ 认证失败 (HTTP 401): 未授权"
|
|
||||||
echo " 请检查以下内容:"
|
|
||||||
echo " 1. DOCKER_USERNAME 和 DOCKER_PASSWORD 是否正确"
|
|
||||||
echo " 2. 如果使用 Access Token,确保有删除镜像的权限"
|
|
||||||
echo " 3. 访问令牌是否过期"
|
|
||||||
echo " 响应详情: $BODY"
|
|
||||||
exit 1
|
|
||||||
elif [ "$HTTP_CODE" = "403" ]; then
|
|
||||||
echo "❌ 权限不足 (HTTP 403): 没有删除镜像的权限"
|
|
||||||
echo " 请确保 Docker Hub 访问令牌具有以下权限:"
|
|
||||||
echo " - Delete repository tags"
|
|
||||||
echo " 响应详情: $BODY"
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo "❌ 删除失败 (HTTP $HTTP_CODE): $BODY"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
name: Delete Docker Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types:
|
||||||
|
- deleted # 当删除 release 时触发
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
delete-image:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Delete Docker image
|
||||||
|
run: |
|
||||||
|
TAG_NAME="${{ github.event.release.tag_name }}"
|
||||||
|
|
||||||
|
# 验证版本号格式:v数字.数字.数字[-后缀](精准匹配)
|
||||||
|
if [[ ! "$TAG_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then
|
||||||
|
echo "警告: 版本号格式不正确 ($TAG_NAME),应为 v数字.数字.数字 或 v数字.数字.数字-后缀 (例如: v1.0.0, v1.0.0-beta)"
|
||||||
|
echo "跳过删除操作"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
IMAGE_NAME="wrbug/polyhermes"
|
||||||
|
DOCKER_USERNAME="${{ secrets.DOCKER_USERNAME }}"
|
||||||
|
DOCKER_PASSWORD="${{ secrets.DOCKER_PASSWORD }}"
|
||||||
|
|
||||||
|
echo "正在删除 Docker 镜像: ${IMAGE_NAME}:${TAG_NAME}"
|
||||||
|
|
||||||
|
# 方法 1: 尝试使用 JWT Token 认证(推荐,适用于 Access Token)
|
||||||
|
# 获取 JWT Token
|
||||||
|
echo "正在获取 Docker Hub JWT Token..."
|
||||||
|
TOKEN_RESPONSE=$(curl -s -X POST \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"username\": \"${DOCKER_USERNAME}\", \"password\": \"${DOCKER_PASSWORD}\"}" \
|
||||||
|
"https://hub.docker.com/v2/users/login/")
|
||||||
|
|
||||||
|
# 提取 Token(支持多种格式)
|
||||||
|
TOKEN=$(echo "$TOKEN_RESPONSE" | grep -oE '"token":"[^"]*"' | head -1 | cut -d'"' -f4)
|
||||||
|
|
||||||
|
if [ -z "$TOKEN" ]; then
|
||||||
|
# 尝试另一种提取方式
|
||||||
|
TOKEN=$(echo "$TOKEN_RESPONSE" | python3 -c "import sys, json; print(json.load(sys.stdin).get('token', ''))" 2>/dev/null || echo "")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$TOKEN" ] && [ "$TOKEN" != "null" ]; then
|
||||||
|
echo "✅ 成功获取 JWT Token,使用 JWT Token 认证"
|
||||||
|
# 使用 JWT Token 删除镜像标签
|
||||||
|
RESPONSE=$(curl -s -w "\n%{http_code}" -X DELETE \
|
||||||
|
-H "Authorization: JWT ${TOKEN}" \
|
||||||
|
"https://hub.docker.com/v2/repositories/${IMAGE_NAME}/tags/${TAG_NAME}/")
|
||||||
|
else
|
||||||
|
echo "⚠️ JWT Token 获取失败,尝试使用 Basic Auth"
|
||||||
|
echo " 如果继续失败,请检查 DOCKER_USERNAME 和 DOCKER_PASSWORD 是否正确"
|
||||||
|
# 方法 2: 使用 Basic Auth(适用于密码)
|
||||||
|
RESPONSE=$(curl -s -w "\n%{http_code}" -X DELETE \
|
||||||
|
-u "${DOCKER_USERNAME}:${DOCKER_PASSWORD}" \
|
||||||
|
"https://hub.docker.com/v2/repositories/${IMAGE_NAME}/tags/${TAG_NAME}/")
|
||||||
|
fi
|
||||||
|
|
||||||
|
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
||||||
|
BODY=$(echo "$RESPONSE" | head -n-1)
|
||||||
|
|
||||||
|
if [ "$HTTP_CODE" = "204" ]; then
|
||||||
|
echo "✅ 成功删除 Docker 镜像标签: ${IMAGE_NAME}:${TAG_NAME}"
|
||||||
|
elif [ "$HTTP_CODE" = "404" ]; then
|
||||||
|
echo "⚠️ 镜像标签不存在: ${IMAGE_NAME}:${TAG_NAME},可能已被删除或不存在"
|
||||||
|
elif [ "$HTTP_CODE" = "401" ]; then
|
||||||
|
echo "❌ 认证失败 (HTTP 401): 未授权"
|
||||||
|
echo " 请检查以下内容:"
|
||||||
|
echo " 1. DOCKER_USERNAME 和 DOCKER_PASSWORD 是否正确"
|
||||||
|
echo " 2. 如果使用 Access Token,确保有删除镜像的权限"
|
||||||
|
echo " 3. 访问令牌是否过期"
|
||||||
|
echo " 响应详情: $BODY"
|
||||||
|
exit 1
|
||||||
|
elif [ "$HTTP_CODE" = "403" ]; then
|
||||||
|
echo "❌ 权限不足 (HTTP 403): 没有删除镜像的权限"
|
||||||
|
echo " 请确保 Docker Hub 访问令牌具有以下权限:"
|
||||||
|
echo " - Delete repository tags"
|
||||||
|
echo " 响应详情: $BODY"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "❌ 删除失败 (HTTP $HTTP_CODE): $BODY"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
@@ -11,7 +11,20 @@
|
|||||||
3. **点击跳转**:点击版本号跳转到对应的 GitHub tag 页面
|
3. **点击跳转**:点击版本号跳转到对应的 GitHub tag 页面
|
||||||
4. **Docker 推送**:自动构建并推送到 Docker Hub
|
4. **Docker 推送**:自动构建并推送到 Docker Hub
|
||||||
5. **自动删除**:删除 release 时自动删除对应的 Docker 镜像标签
|
5. **自动删除**:删除 release 时自动删除对应的 Docker 镜像标签
|
||||||
6. **版本号验证**:精准匹配版本号格式 `v数字.数字.数字`(例如:`v1.0.0`, `v2.10.102`)
|
6. **版本号验证**:精准匹配版本号格式 `v数字.数字.数字` 或 `v数字.数字.数字-后缀`(例如:`v1.0.0`, `v1.0.0-beta`)
|
||||||
|
7. **独立脚本**:构建和删除功能分离到不同的 workflow 文件,便于管理和维护
|
||||||
|
|
||||||
|
## Workflow 文件说明
|
||||||
|
|
||||||
|
项目使用两个独立的 GitHub Actions workflow 文件:
|
||||||
|
|
||||||
|
- **`.github/workflows/docker-build.yml`**:负责构建和推送 Docker 镜像
|
||||||
|
- 触发条件:`release: published`(创建 release 时)
|
||||||
|
- 功能:提取版本号、构建多架构镜像、推送到 Docker Hub
|
||||||
|
|
||||||
|
- **`.github/workflows/docker-delete.yml`**:负责删除 Docker 镜像
|
||||||
|
- 触发条件:`release: deleted`(删除 release 时)
|
||||||
|
- 功能:验证版本号格式、删除对应的 Docker 镜像标签
|
||||||
|
|
||||||
## 使用方法
|
## 使用方法
|
||||||
|
|
||||||
@@ -48,6 +61,10 @@
|
|||||||
|
|
||||||
**重要**:只有通过 [GitHub Releases 页面](https://github.com/WrBug/PolyHermes/releases/new) 创建 release 时才会触发自动构建。
|
**重要**:只有通过 [GitHub Releases 页面](https://github.com/WrBug/PolyHermes/releases/new) 创建 release 时才会触发自动构建。
|
||||||
|
|
||||||
|
**Workflow 说明**:
|
||||||
|
- 创建 release 时,会触发 `docker-build.yml` workflow,自动构建并推送镜像
|
||||||
|
- 删除 release 时,会触发 `docker-delete.yml` workflow,自动删除对应的镜像标签
|
||||||
|
|
||||||
**创建步骤**:
|
**创建步骤**:
|
||||||
1. 访问 [GitHub Releases 页面](https://github.com/WrBug/PolyHermes/releases/new)
|
1. 访问 [GitHub Releases 页面](https://github.com/WrBug/PolyHermes/releases/new)
|
||||||
2. 点击 "Choose a tag" 下拉菜单,输入新的 tag 名称(例如:`v1.0.0` 或 `v1.0.0-beta`)
|
2. 点击 "Choose a tag" 下拉菜单,输入新的 tag 名称(例如:`v1.0.0` 或 `v1.0.0-beta`)
|
||||||
|
|||||||
Reference in New Issue
Block a user