复制项目
This commit is contained in:
255
.gitea/SECRETS_CONFIG.md
Normal file
255
.gitea/SECRETS_CONFIG.md
Normal file
@@ -0,0 +1,255 @@
|
||||
# OpenIM Server 项目 Gitea Actions 秘钥配置指南
|
||||
|
||||
## 📋 概述
|
||||
|
||||
本指南说明如何在 Gitea 中配置必要的秘钥,以支持 OpenIM Server 项目的自动构建和部署到阿里云 ACK。
|
||||
|
||||
## 🔑 必需秘钥配置
|
||||
|
||||
### 1. Docker Hub 相关秘钥
|
||||
|
||||
#### DOCKER_USERNAME
|
||||
- **描述**: Docker Hub 用户名
|
||||
- **示例**: `openim`
|
||||
- **获取方式**: 在 Docker Hub 注册账号
|
||||
|
||||
#### DOCKER_PASSWORD
|
||||
- **描述**: Docker Hub 密码或访问令牌
|
||||
- **示例**: `your-docker-password` 或 `dckr_pat_xxxxxxxxxxxx`
|
||||
- **推荐**: 使用访问令牌(Access Token)而不是密码
|
||||
- **获取方式**:
|
||||
1. 登录 Docker Hub
|
||||
2. 进入 Account Settings → Security
|
||||
3. 创建 New Access Token
|
||||
|
||||
### 2. 阿里云 ACK 相关秘钥
|
||||
|
||||
#### KUBECONFIG
|
||||
- **描述**: 阿里云 ACK 集群的 kubeconfig 内容(base64编码)
|
||||
- **格式**: base64编码的YAML格式kubeconfig文件内容
|
||||
- **获取方式**: 见下方详细说明
|
||||
|
||||
#### ALIBABA_CLOUD_ACCESS_KEY_ID (可选)
|
||||
- **描述**: 阿里云AccessKey ID
|
||||
- **用途**: 用于通过aliyun CLI获取kubeconfig
|
||||
- **获取方式**: 阿里云控制台 → 访问控制 → AccessKey管理
|
||||
|
||||
#### ALIBABA_CLOUD_ACCESS_KEY_SECRET (可选)
|
||||
- **描述**: 阿里云AccessKey Secret
|
||||
- **用途**: 用于通过aliyun CLI获取kubeconfig
|
||||
- **获取方式**: 阿里云控制台 → 访问控制 → AccessKey管理
|
||||
|
||||
#### ACK_CLUSTER_ID (可选)
|
||||
- **描述**: 阿里云ACK集群ID
|
||||
- **用途**: 用于通过aliyun CLI获取kubeconfig
|
||||
- **获取方式**: ACK控制台集群详情页
|
||||
|
||||
#### ACK_REGION (可选)
|
||||
- **描述**: 阿里云ACK集群区域
|
||||
- **默认值**: `cn-hangzhou`
|
||||
- **示例**: `cn-beijing`, `cn-shanghai`, `cn-shenzhen`
|
||||
|
||||
#### NAMESPACE (可选)
|
||||
- **描述**: Kubernetes命名空间
|
||||
- **默认值**: `openim`
|
||||
- **示例**: `openim`, `default`, `production`
|
||||
|
||||
## 🚀 获取阿里云 ACK KUBECONFIG
|
||||
|
||||
### 方法1: 通过阿里云控制台(推荐)
|
||||
|
||||
1. **登录阿里云控制台**
|
||||
- 访问 [阿里云容器服务控制台](https://cs.console.aliyun.com/)
|
||||
|
||||
2. **选择集群**
|
||||
- 进入目标 ACK 集群详情页
|
||||
|
||||
3. **获取连接信息**
|
||||
- 点击 "连接信息" 标签
|
||||
- 复制 "公网访问" 或 "内网访问" 的 kubeconfig 内容
|
||||
|
||||
4. **编码kubeconfig**
|
||||
```bash
|
||||
# 将获取的kubeconfig内容保存到文件
|
||||
cat > kubeconfig.yaml << 'EOF'
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: LS0tLS1CRUdJTi...
|
||||
server: https://your-cluster-id.cn-hangzhou.cs.aliyuncs.com:6443
|
||||
name: kubernetes
|
||||
contexts:
|
||||
- context:
|
||||
cluster: kubernetes
|
||||
user: your-user
|
||||
name: kubernetes
|
||||
current-context: kubernetes
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: your-user
|
||||
user:
|
||||
client-certificate-data: LS0tLS1CRUdJTi...
|
||||
client-key-data: LS0tLS1CRUdJTi...
|
||||
EOF
|
||||
|
||||
# 编码为base64
|
||||
base64 -w 0 kubeconfig.yaml
|
||||
```
|
||||
|
||||
### 方法2: 通过阿里云 CLI
|
||||
|
||||
1. **安装阿里云 CLI**
|
||||
```bash
|
||||
# macOS
|
||||
brew install aliyun-cli
|
||||
|
||||
# Linux
|
||||
curl -sSL https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz | tar -xzC /usr/local/bin
|
||||
```
|
||||
|
||||
2. **配置认证**
|
||||
```bash
|
||||
aliyun configure
|
||||
# 输入 AccessKey ID 和 AccessKey Secret
|
||||
```
|
||||
|
||||
3. **获取kubeconfig并编码**
|
||||
```bash
|
||||
# 获取指定集群的kubeconfig
|
||||
aliyun cs GET /k8s/clusters/{cluster_id}/user_config > kubeconfig.yaml
|
||||
|
||||
# 编码为base64
|
||||
base64 -w 0 kubeconfig.yaml
|
||||
```
|
||||
|
||||
## 🔧 在 Gitea 中配置秘钥
|
||||
|
||||
### 1. 进入仓库设置
|
||||
|
||||
1. 打开 OpenIM Server 项目仓库
|
||||
2. 点击 "Settings" 标签
|
||||
3. 在左侧菜单中点击 "Secrets"
|
||||
|
||||
### 2. 添加秘钥
|
||||
|
||||
点击 "New Secret" 按钮,依次添加以下秘钥:
|
||||
|
||||
#### 必需秘钥
|
||||
|
||||
##### DOCKER_USERNAME
|
||||
- **Name**: `DOCKER_USERNAME`
|
||||
- **Value**: 你的 Docker Hub 用户名
|
||||
|
||||
##### DOCKER_PASSWORD
|
||||
- **Name**: `DOCKER_PASSWORD`
|
||||
- **Value**: 你的 Docker Hub 密码或访问令牌
|
||||
|
||||
##### KUBECONFIG
|
||||
- **Name**: `KUBECONFIG`
|
||||
- **Value**: base64编码的kubeconfig文件内容
|
||||
|
||||
#### 可选秘钥
|
||||
|
||||
##### ALIBABA_CLOUD_ACCESS_KEY_ID
|
||||
- **Name**: `ALIBABA_CLOUD_ACCESS_KEY_ID`
|
||||
- **Value**: 阿里云AccessKey ID
|
||||
|
||||
##### ALIBABA_CLOUD_ACCESS_KEY_SECRET
|
||||
- **Name**: `ALIBABA_CLOUD_ACCESS_KEY_SECRET`
|
||||
- **Value**: 阿里云AccessKey Secret
|
||||
|
||||
##### ACK_CLUSTER_ID
|
||||
- **Name**: `ACK_CLUSTER_ID`
|
||||
- **Value**: ACK集群ID
|
||||
|
||||
##### ACK_REGION
|
||||
- **Name**: `ACK_REGION`
|
||||
- **Value**: ACK集群区域(默认:cn-hangzhou)
|
||||
|
||||
##### NAMESPACE
|
||||
- **Name**: `NAMESPACE`
|
||||
- **Value**: Kubernetes命名空间(默认:openim)
|
||||
|
||||
## 🚨 安全注意事项
|
||||
|
||||
### 1. 秘钥安全
|
||||
- **不要** 将秘钥提交到代码仓库
|
||||
- **定期轮换** 访问令牌和密码
|
||||
- **使用最小权限** 原则配置访问权限
|
||||
|
||||
### 2. KUBECONFIG 安全
|
||||
- **限制权限**: 确保kubeconfig只有必要的权限
|
||||
- **定期更新**: 定期更新证书和密钥
|
||||
- **监控访问**: 监控集群访问日志
|
||||
|
||||
### 3. Docker Hub 安全
|
||||
- **使用访问令牌**: 优先使用访问令牌而不是密码
|
||||
- **限制权限**: 只授予必要的仓库推送权限
|
||||
- **定期轮换**: 定期更新访问令牌
|
||||
|
||||
## 🔍 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
#### 1. Docker 登录失败
|
||||
```
|
||||
Error: Cannot perform an interactive login from a non TTY device
|
||||
```
|
||||
**解决方案**: 检查 `DOCKER_USERNAME` 和 `DOCKER_PASSWORD` 是否正确配置
|
||||
|
||||
#### 2. kubectl 连接失败
|
||||
```
|
||||
Unable to connect to the server: x509: certificate signed by unknown authority
|
||||
```
|
||||
**解决方案**: 检查 `KUBECONFIG` 中的证书数据是否正确
|
||||
|
||||
#### 3. 镜像拉取失败
|
||||
```
|
||||
Error: pull access denied for openim/openim-api
|
||||
```
|
||||
**解决方案**: 检查 Docker Hub 权限和镜像名称是否正确
|
||||
|
||||
#### 4. 部署超时
|
||||
```
|
||||
deployment "openim-api" exceeded its progress deadline
|
||||
```
|
||||
**解决方案**: 检查集群资源是否充足,Pod 是否正常启动
|
||||
|
||||
### 调试命令
|
||||
|
||||
```bash
|
||||
# 检查秘钥是否正确设置
|
||||
echo "Docker username: $DOCKER_USERNAME"
|
||||
echo "Kubeconfig length: ${#KUBECONFIG}"
|
||||
|
||||
# 测试 Docker 登录
|
||||
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
|
||||
|
||||
# 测试 kubectl 连接
|
||||
echo "$KUBECONFIG" | base64 -d > ~/.kube/config
|
||||
kubectl cluster-info
|
||||
kubectl get nodes
|
||||
```
|
||||
|
||||
## 📚 参考文档
|
||||
|
||||
- [Gitea Actions 文档](https://docs.gitea.io/en-us/actions/)
|
||||
- [阿里云 ACK 文档](https://help.aliyun.com/product/85222.html)
|
||||
- [Docker Hub 访问令牌](https://docs.docker.com/docker-hub/access-tokens/)
|
||||
- [Kubernetes kubeconfig](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/)
|
||||
- [OpenIM 官方文档](https://docs.openim.io/)
|
||||
|
||||
## 🆘 支持
|
||||
|
||||
如遇到问题,请检查:
|
||||
1. 秘钥是否正确配置
|
||||
2. 网络连接是否正常
|
||||
3. 权限是否充足
|
||||
4. 集群状态是否正常
|
||||
|
||||
更多帮助请参考:
|
||||
- Gitea Actions 日志
|
||||
- 阿里云 ACK 控制台
|
||||
- Docker Hub 状态页面
|
||||
- OpenIM 官方文档
|
||||
535
.gitea/workflows/build.yml
Normal file
535
.gitea/workflows/build.yml
Normal file
@@ -0,0 +1,535 @@
|
||||
name: OpenIM Server 构建和发布
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, master, wallet, develop, release-* ]
|
||||
paths:
|
||||
- '**'
|
||||
pull_request:
|
||||
branches: [ main, master, wallet ]
|
||||
paths:
|
||||
- '**'
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: "Tag version to be used for Docker image"
|
||||
required: true
|
||||
default: "latest"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
REGISTRY: docker.io
|
||||
DOCKER_USER: ${{ secrets.DOCKER_USERNAME || 'mag1666888' }}
|
||||
GO_VERSION: "1.24"
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: openim
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: 检出代码
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 配置 SSH 密钥
|
||||
run: |
|
||||
echo "🔑 配置 SSH 密钥..."
|
||||
# 创建 .ssh 目录
|
||||
mkdir -p ~/.ssh
|
||||
chmod 700 ~/.ssh
|
||||
|
||||
# 从 secrets 中获取 SSH 私钥并 base64 解码
|
||||
echo "${{ secrets.SSH_PRIVATE_KEY }}" | base64 -d > ~/.ssh/id_rsa
|
||||
chmod 600 ~/.ssh/id_rsa
|
||||
|
||||
# 配置 SSH 主机密钥验证(可选,避免首次连接时的确认提示)
|
||||
ssh-keyscan -H git.imall.cloud >> ~/.ssh/known_hosts 2>/dev/null || true
|
||||
chmod 644 ~/.ssh/known_hosts
|
||||
|
||||
# 验证 SSH 密钥
|
||||
if [ -f ~/.ssh/id_rsa ]; then
|
||||
echo "✅ SSH 密钥配置成功"
|
||||
else
|
||||
echo "❌ SSH 密钥配置失败"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: 检出 protocol 仓库
|
||||
run: |
|
||||
echo "📦 克隆 protocol 仓库..."
|
||||
# 使用 SSH 方式克隆 protocol 仓库
|
||||
git clone git@git.imall.cloud:openim/protocol.git ./protocol || true
|
||||
cd ./protocol
|
||||
git fetch --all
|
||||
git checkout v1.0.4
|
||||
cd ..
|
||||
# 创建父目录的protocol符号链接,使replace ../protocol 能正确找到
|
||||
ln -sf $PWD/protocol ../protocol || true
|
||||
echo "✅ protocol 仓库检出完成"
|
||||
|
||||
- name: 设置 Go 缓存
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: 设置 Go 环境
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache: true
|
||||
|
||||
- name: 检查 Go 环境
|
||||
run: |
|
||||
if command -v go &> /dev/null; then
|
||||
echo "Go: $(go version)"
|
||||
go mod verify >/dev/null 2>&1
|
||||
go mod tidy >/dev/null 2>&1
|
||||
go mod download >/dev/null 2>&1
|
||||
echo "Go modules verified"
|
||||
else
|
||||
echo "Go not found, skipping Go steps"
|
||||
fi
|
||||
|
||||
- name: 检查系统资源
|
||||
run: |
|
||||
echo "系统资源信息:"
|
||||
echo "CPU核心数: $(nproc)"
|
||||
echo "内存总量: $(free -h | awk '/^Mem:/ {print $2}')"
|
||||
echo "可用内存: $(free -h | awk '/^Mem:/ {print $7}')"
|
||||
echo "磁盘空间: $(df -h / | awk 'NR==2 {print $4}')"
|
||||
echo ""
|
||||
|
||||
- name: 清理 Docker 环境
|
||||
run: |
|
||||
echo "清理Docker环境..."
|
||||
docker image prune -f >/dev/null 2>&1 || true
|
||||
|
||||
- name: 登录到 Docker Hub
|
||||
uses: docker/login-action@v3.3.0
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: 设置 Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3.8.0
|
||||
with:
|
||||
driver-opts: |
|
||||
image=moby/buildkit:buildx-stable-1
|
||||
network=host
|
||||
|
||||
- name: 构建和推送所有服务镜像
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: |
|
||||
# 设置错误处理
|
||||
trap 'echo "脚本在行 $LINENO 处失败,退出状态: $?"' ERR
|
||||
set -e
|
||||
|
||||
# 获取版本标签(使用分支名)
|
||||
if [ "${{ github.event_name }}" = "release" ]; then
|
||||
VERSION_TAG="${{ github.event.release.tag_name }}"
|
||||
elif [ -n "${{ github.event.inputs.tag }}" ]; then
|
||||
VERSION_TAG="${{ github.event.inputs.tag }}"
|
||||
else
|
||||
# 使用分支名作为标签
|
||||
VERSION_TAG="${{ github.ref_name }}"
|
||||
fi
|
||||
|
||||
echo "构建OpenIM Server镜像 (标签: $VERSION_TAG)"
|
||||
echo "Docker用户: $DOCKER_USER"
|
||||
|
||||
# 定义构建顺序(openim-msggateway 和 openim-push 优先构建)
|
||||
CORE_SERVICES=(
|
||||
"openim-msggateway"
|
||||
"openim-push"
|
||||
"openim-rpc-msg"
|
||||
"openim-api"
|
||||
"openim-msgtransfer"
|
||||
"openim-crontask"
|
||||
)
|
||||
|
||||
RPC_SERVICES=(
|
||||
"openim-rpc-auth"
|
||||
"openim-rpc-user"
|
||||
"openim-rpc-friend"
|
||||
"openim-rpc-group"
|
||||
"openim-rpc-conversation"
|
||||
"openim-rpc-third"
|
||||
)
|
||||
|
||||
# 构建函数
|
||||
build_service() {
|
||||
local service=$1
|
||||
local dockerfile="build/images/$service/Dockerfile"
|
||||
local start_time=$(date +%s)
|
||||
|
||||
if [ -f "$dockerfile" ]; then
|
||||
echo "📦 构建 $service..."
|
||||
|
||||
if docker buildx build \
|
||||
--platform linux/amd64 \
|
||||
--file "$dockerfile" \
|
||||
--tag "$DOCKER_USER/$service:$VERSION_TAG" \
|
||||
--tag "$DOCKER_USER/$service:prod" \
|
||||
--push \
|
||||
--progress=plain \
|
||||
--cache-from type=gha,scope=openim-build-${{ github.ref_name }}-$service \
|
||||
--cache-to type=gha,mode=max,scope=openim-build-${{ github.ref_name }}-$service \
|
||||
--build-arg BUILDKIT_INLINE_CACHE=1 \
|
||||
--build-arg GOCACHE=/go-cache \
|
||||
--build-arg GOMAXPROCS=$(nproc) \
|
||||
--provenance=false \
|
||||
--sbom=false \
|
||||
. > "/tmp/build_${service}.log" 2>&1; then
|
||||
|
||||
local end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
echo "✅ $service 构建成功 (${duration}秒)"
|
||||
else
|
||||
echo "❌ $service 构建失败,查看详细错误日志:"
|
||||
echo "=========================================="
|
||||
cat "/tmp/build_${service}.log"
|
||||
echo "=========================================="
|
||||
echo "最后 50 行错误日志:"
|
||||
tail -50 "/tmp/build_${service}.log"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
echo "❌ $service - 未找到 Dockerfile: $dockerfile"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 初始化构建统计
|
||||
failed_services=()
|
||||
successful_services=()
|
||||
|
||||
# 计算总服务数
|
||||
total_services=$((${#CORE_SERVICES[@]} + ${#RPC_SERVICES[@]}))
|
||||
echo "开始构建 $total_services 个服务..."
|
||||
|
||||
# 先构建核心服务
|
||||
for service in "${CORE_SERVICES[@]}"; do
|
||||
if build_service "$service"; then
|
||||
successful_services+=("$service")
|
||||
else
|
||||
failed_services+=("$service")
|
||||
fi
|
||||
done
|
||||
|
||||
# 构建RPC服务
|
||||
for service in "${RPC_SERVICES[@]}"; do
|
||||
if build_service "$service"; then
|
||||
successful_services+=("$service")
|
||||
else
|
||||
failed_services+=("$service")
|
||||
fi
|
||||
done
|
||||
|
||||
# 输出构建结果统计
|
||||
echo ""
|
||||
echo "🎉 构建完成总结"
|
||||
echo "✅ 成功构建: ${#successful_services[@]} 个服务"
|
||||
echo "❌ 构建失败: ${#failed_services[@]} 个服务"
|
||||
echo "📊 成功率: $(( ${#successful_services[@]} * 100 / total_services ))%"
|
||||
|
||||
if [ ${#failed_services[@]} -gt 0 ]; then
|
||||
echo ""
|
||||
echo "失败服务错误日志:"
|
||||
for service in "${failed_services[@]}"; do
|
||||
echo "=== $service ==="
|
||||
cat "/tmp/build_${service}.log" 2>/dev/null || echo "无法读取日志文件"
|
||||
echo ""
|
||||
done
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: 配置 kubectl
|
||||
if: success()
|
||||
run: |
|
||||
echo "🔧 配置 kubectl 连接到阿里云 ACK..."
|
||||
# 创建 kubeconfig 目录
|
||||
mkdir -p ~/.kube
|
||||
|
||||
# 从 secrets 中获取 kubeconfig 内容并处理
|
||||
echo "📝 处理 kubeconfig 文件..."
|
||||
|
||||
# 直接解码 base64 内容
|
||||
echo "🔍 解码 base64 编码的 kubeconfig..."
|
||||
echo "${{ secrets.KUBECONFIG }}" | base64 -d > ~/.kube/config
|
||||
|
||||
# 验证解码是否成功
|
||||
if [ ! -s ~/.kube/config ]; then
|
||||
echo "❌ kubeconfig 解码失败或文件为空"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 显示 kubeconfig 内容供手动检查
|
||||
echo "🔍 解码后的 kubeconfig 内容:"
|
||||
cat ~/.kube/config
|
||||
|
||||
chmod 600 ~/.kube/config
|
||||
echo "✅ kubeconfig 配置完成"
|
||||
|
||||
# 详细验证 kubectl 配置
|
||||
echo "🔍 验证 kubectl 配置..."
|
||||
echo "当前上下文:"
|
||||
kubectl config current-context 2>&1 || echo "无法获取当前上下文"
|
||||
|
||||
echo "可用上下文:"
|
||||
kubectl config get-contexts 2>&1 || echo "无法获取上下文列表"
|
||||
|
||||
echo "集群信息:"
|
||||
kubectl cluster-info 2>&1 || echo "无法获取集群信息"
|
||||
|
||||
echo "API 版本:"
|
||||
kubectl version --short 2>&1 || echo "无法获取版本信息"
|
||||
|
||||
- name: 部署到阿里云 ACK
|
||||
if: success()
|
||||
run: |
|
||||
echo "🚀 开始部署到阿里云 ACK..."
|
||||
|
||||
# 简单验证 kubectl
|
||||
if ! kubectl version --client >/dev/null 2>&1; then
|
||||
echo "❌ kubectl 不可用,跳过部署步骤"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "✅ kubectl 可用,尝试部署..."
|
||||
|
||||
# 获取版本标签(使用分支名)
|
||||
if [ "${{ github.event_name }}" = "release" ]; then
|
||||
VERSION_TAG="${{ github.event.release.tag_name }}"
|
||||
elif [ -n "${{ github.event.inputs.tag }}" ]; then
|
||||
VERSION_TAG="${{ github.event.inputs.tag }}"
|
||||
else
|
||||
# 使用分支名作为标签
|
||||
VERSION_TAG="${{ github.ref_name }}"
|
||||
fi
|
||||
|
||||
echo "版本标签: $VERSION_TAG"
|
||||
echo "Docker用户: $DOCKER_USER"
|
||||
|
||||
# 检查部署文件是否存在
|
||||
DEPLOY_DIR="deployments/deploy"
|
||||
if [ ! -d "$DEPLOY_DIR" ]; then
|
||||
echo "❌ 部署目录不存在: $DEPLOY_DIR"
|
||||
echo "📁 当前目录内容:"
|
||||
ls -la
|
||||
echo "⚠️ 部署失败,但构建流程继续"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "📁 进入部署目录: $DEPLOY_DIR"
|
||||
cd "$DEPLOY_DIR"
|
||||
|
||||
# 设置命名空间
|
||||
NS=${NS:-default}
|
||||
echo "使用命名空间: $NS"
|
||||
|
||||
# 创建命名空间(如果不存在)
|
||||
kubectl get ns "$NS" >/dev/null 2>&1 || kubectl create ns "$NS"
|
||||
kubectl config set-context --current --namespace="$NS"
|
||||
|
||||
# 尝试部署,如果失败则继续
|
||||
echo "🚀 开始部署OpenIM Server服务..."
|
||||
|
||||
# 定义所有部署文件
|
||||
DEPLOYMENT_FILES=(
|
||||
"openim-api-deployment.yml"
|
||||
"openim-crontask-deployment.yml"
|
||||
"openim-rpc-user-deployment.yml"
|
||||
"openim-msggateway-deployment.yml"
|
||||
"openim-push-deployment.yml"
|
||||
"openim-msgtransfer-deployment.yml"
|
||||
"openim-rpc-conversation-deployment.yml"
|
||||
"openim-rpc-auth-deployment.yml"
|
||||
"openim-rpc-group-deployment.yml"
|
||||
"openim-rpc-friend-deployment.yml"
|
||||
"openim-rpc-msg-deployment.yml"
|
||||
"openim-rpc-third-deployment.yml"
|
||||
)
|
||||
|
||||
# 更新镜像标签并部署
|
||||
DEPLOYMENT_ERRORS=()
|
||||
for file in "${DEPLOYMENT_FILES[@]}"; do
|
||||
if [ -f "$file" ]; then
|
||||
echo "📦 处理 $file..."
|
||||
# 备份原文件(保留 imagePullSecrets 等配置)
|
||||
cp "$file" "$file.bak"
|
||||
# 更新镜像标签(替换用户名和标签,但保留 imagePullSecrets)
|
||||
sed -i "s|image: .*/openim-|image: $DOCKER_USER/openim-|g" "$file"
|
||||
sed -i "s|:prod|:prod|g" "$file"
|
||||
# 验证 imagePullSecrets 是否保留
|
||||
if ! grep -q "imagePullSecrets:" "$file"; then
|
||||
echo "⚠️ 警告: $file 中缺少 imagePullSecrets,从备份恢复..."
|
||||
cp "$file.bak" "$file"
|
||||
# 只更新镜像,不修改其他内容
|
||||
sed -i "s|image: .*/openim-|image: $DOCKER_USER/openim-|g" "$file"
|
||||
sed -i "s|:prod|:prod|g" "$file"
|
||||
fi
|
||||
# 应用文件并捕获详细错误
|
||||
echo "🔍 执行: kubectl apply -f $file"
|
||||
if kubectl apply -f "$file" 2>&1; then
|
||||
echo "✅ $file 部署成功"
|
||||
else
|
||||
ERROR_OUTPUT=$(kubectl apply -f "$file" 2>&1)
|
||||
echo "❌ $file 部署失败:"
|
||||
echo "$ERROR_OUTPUT"
|
||||
DEPLOYMENT_ERRORS+=("$file: $ERROR_OUTPUT")
|
||||
echo "⚠️ 继续处理下一个文件..."
|
||||
fi
|
||||
# 清理备份文件
|
||||
rm -f "$file.bak"
|
||||
else
|
||||
echo "⚠️ $file 不存在,跳过"
|
||||
fi
|
||||
done
|
||||
|
||||
# 显示部署错误总结
|
||||
if [ ${#DEPLOYMENT_ERRORS[@]} -gt 0 ]; then
|
||||
echo ""
|
||||
echo "🚨 部署错误总结:"
|
||||
echo "=========================================="
|
||||
for error in "${DEPLOYMENT_ERRORS[@]}"; do
|
||||
echo "❌ $error"
|
||||
done
|
||||
echo "=========================================="
|
||||
fi
|
||||
|
||||
echo "✅ 部署步骤完成"
|
||||
|
||||
# 强制重启所有部署以使用新镜像
|
||||
echo "🔄 强制重启所有部署以使用新镜像..."
|
||||
DEPLOYMENTS=(
|
||||
"openim-api"
|
||||
"openim-crontask"
|
||||
"messagegateway-rpc-server"
|
||||
"openim-msgtransfer-server"
|
||||
"push-rpc-server"
|
||||
"auth-rpc-server"
|
||||
"user-rpc-server"
|
||||
"friend-rpc-server"
|
||||
"group-rpc-server"
|
||||
"conversation-rpc-server"
|
||||
"third-rpc-server"
|
||||
"msg-rpc-server"
|
||||
)
|
||||
|
||||
for deployment in "${DEPLOYMENTS[@]}"; do
|
||||
echo "🔄 重启部署: $deployment"
|
||||
# 先删除 pod 以强制拉取新镜像(即使 imagePullPolicy 是 Always,有时也需要删除 pod)
|
||||
if kubectl delete pods -l app="$deployment" --grace-period=0 --force 2>&1; then
|
||||
echo "✅ $deployment Pod 已删除,将重新创建并拉取新镜像"
|
||||
fi
|
||||
# 然后重启 deployment
|
||||
if kubectl rollout restart deployment "$deployment" 2>&1; then
|
||||
echo "✅ $deployment 重启成功"
|
||||
else
|
||||
echo "⚠️ $deployment 重启失败,可能不存在"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "⏳ 等待部署完成..."
|
||||
for deployment in "${DEPLOYMENTS[@]}"; do
|
||||
echo "⏳ 等待 $deployment 就绪..."
|
||||
if kubectl rollout status deployment "$deployment" --timeout=300s; then
|
||||
echo "✅ $deployment 部署完成"
|
||||
else
|
||||
echo "⚠️ $deployment 超时,检查Pod状态..."
|
||||
echo "Pod状态:"
|
||||
kubectl get pods -l app="$deployment" 2>&1 || echo "无法获取Pod状态"
|
||||
echo "Pod事件:"
|
||||
kubectl get events --field-selector involvedObject.name="$deployment" --sort-by='.lastTimestamp' 2>&1 | tail -10 || echo "无法获取事件"
|
||||
echo "部署详情:"
|
||||
kubectl describe deployment "$deployment" 2>&1 | tail -20 || echo "无法获取部署详情"
|
||||
fi
|
||||
done
|
||||
|
||||
- name: 验证部署状态
|
||||
if: success()
|
||||
run: |
|
||||
echo "🔍 验证部署状态..."
|
||||
|
||||
# 详细检查集群连接和权限
|
||||
echo "🔍 检查集群连接..."
|
||||
if kubectl cluster-info 2>&1; then
|
||||
echo "✅ 集群连接正常"
|
||||
else
|
||||
CLUSTER_ERROR=$(kubectl cluster-info 2>&1)
|
||||
echo "❌ 集群连接失败: $CLUSTER_ERROR"
|
||||
fi
|
||||
|
||||
echo "🔍 检查命名空间权限..."
|
||||
if kubectl get namespaces 2>&1; then
|
||||
echo "✅ 命名空间权限正常"
|
||||
else
|
||||
NS_ERROR=$(kubectl get namespaces 2>&1)
|
||||
echo "❌ 命名空间权限不足: $NS_ERROR"
|
||||
fi
|
||||
|
||||
echo "🔍 检查 Pod 状态..."
|
||||
if kubectl get pods -l app=openim 2>&1; then
|
||||
echo "✅ Pod 状态检查完成"
|
||||
else
|
||||
POD_ERROR=$(kubectl get pods -l app=openim 2>&1)
|
||||
echo "❌ Pod 状态检查失败: $POD_ERROR"
|
||||
fi
|
||||
|
||||
echo "🔍 检查部署状态..."
|
||||
if kubectl get deployments -l app=openim 2>&1; then
|
||||
echo "✅ 部署状态检查完成"
|
||||
else
|
||||
DEPLOY_ERROR=$(kubectl get deployments -l app=openim 2>&1)
|
||||
echo "❌ 部署状态检查失败: $DEPLOY_ERROR"
|
||||
fi
|
||||
|
||||
echo "✅ 验证完成"
|
||||
|
||||
- name: 生成构建报告
|
||||
run: |
|
||||
# 获取版本标签(使用分支名)
|
||||
if [ "${{ github.event_name }}" = "release" ]; then
|
||||
VERSION_TAG="${{ github.event.release.tag_name }}"
|
||||
elif [ -n "${{ github.event.inputs.tag }}" ]; then
|
||||
VERSION_TAG="${{ github.event.inputs.tag }}"
|
||||
else
|
||||
# 使用分支名作为标签
|
||||
VERSION_TAG="${{ github.ref_name }}"
|
||||
fi
|
||||
|
||||
echo "## OpenIM Server Build Complete" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Tag:** $VERSION_TAG" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Branch:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Platform:** linux/amd64" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Mode:** 完整构建和部署" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Images:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`$DOCKER_USER/openim-api:$VERSION_TAG\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`$DOCKER_USER/openim-msggateway:$VERSION_TAG\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`$DOCKER_USER/openim-msgtransfer:$VERSION_TAG\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`$DOCKER_USER/openim-push:$VERSION_TAG\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`$DOCKER_USER/openim-crontask:$VERSION_TAG\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`$DOCKER_USER/openim-rpc-auth:$VERSION_TAG\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`$DOCKER_USER/openim-rpc-user:$VERSION_TAG\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`$DOCKER_USER/openim-rpc-friend:$VERSION_TAG\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`$DOCKER_USER/openim-rpc-group:$VERSION_TAG\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`$DOCKER_USER/openim-rpc-conversation:$VERSION_TAG\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`$DOCKER_USER/openim-rpc-third:$VERSION_TAG\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`$DOCKER_USER/openim-rpc-msg:$VERSION_TAG\`" >> $GITHUB_STEP_SUMMARY
|
||||
Reference in New Issue
Block a user