Skip to content

Commit 3102571

Browse files
committed
优化构建流程和多平台发布
- 修复 golangci-lint 所有代码质量问题 - 更新 GitHub Actions 工作流,支持更好的多平台构建 - 添加本地多平台构建脚本 build-release.sh - 更新 Makefile 添加 release-all 目标 - 改进发布包结构,包含 README 和启动脚本 - 修复 Go 版本配置 (1.23) - 增强错误处理和日志记录
1 parent 26b9764 commit 3102571

File tree

6 files changed

+206
-11
lines changed

6 files changed

+206
-11
lines changed

.github/workflows/build.yml

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ jobs:
8282
-ldflags="-s -w -X main.version=${VERSION} -X main.commit=${COMMIT} -X main.date=${DATE}" \
8383
-o ${{ matrix.output }} .
8484
85+
# 确保 Linux/macOS 二进制文件有执行权限
86+
if [[ "${{ matrix.goos }}" != "windows" ]]; then
87+
chmod +x ${{ matrix.output }}
88+
fi
89+
90+
# 验证生成的文件
91+
ls -la ${{ matrix.output }}
92+
file ${{ matrix.output }}
93+
8594
- name: Create build info
8695
run: |
8796
echo "Build Info:" > build-info-${{ matrix.goos }}-${{ matrix.goarch }}.txt
@@ -241,15 +250,19 @@ jobs:
241250
cd "$dir"
242251
243252
# 找到可执行文件
244-
executable=$(find . -name "filecodebox*" -executable -type f | head -1)
253+
executable=$(find . -name "filecodebox*" -type f | head -1)
245254
if [ -n "$executable" ]; then
255+
echo "Found executable: $executable"
256+
246257
# 创建发布目录
247258
release_name="filecodebox-${platform}"
248259
mkdir -p "../release-assets/$release_name"
249260
250261
# 复制文件
251262
cp "$executable" "../release-assets/$release_name/"
252-
cp build-info-*.txt "../release-assets/$release_name/" 2>/dev/null || true
263+
if [ -f "build-info-*.txt" ]; then
264+
cp build-info-*.txt "../release-assets/$release_name/" 2>/dev/null || true
265+
fi
253266
254267
# 创建README
255268
cat > "../release-assets/$release_name/README.txt" << EOF
@@ -275,11 +288,18 @@ jobs:
275288
tar -czf "${release_name}.tar.gz" "$release_name/"
276289
fi
277290
rm -rf "$release_name"
291+
else
292+
echo "No executable found in $dir"
293+
ls -la "$dir"
278294
fi
279295
280296
cd - > /dev/null
281297
fi
282298
done
299+
300+
# 列出所有生成的文件
301+
echo "Generated release assets:"
302+
ls -la release-assets/
283303
284304
- name: Generate release notes
285305
run: |

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ release:
2626
@echo "Building FileCodeBox release $(VERSION) ($(COMMIT)) at $(DATE)"
2727
CGO_ENABLED=0 go build $(LDFLAGS) -a -installsuffix cgo -o filecodebox .
2828

29+
# 多平台发布构建
30+
release-all:
31+
@echo "Building FileCodeBox for all platforms..."
32+
./build-release.sh $(VERSION)
33+
2934
# 运行项目
3035
run: build
3136
./filecodebox
@@ -48,6 +53,7 @@ dev:
4853
# 清理编译文件
4954
clean:
5055
rm -f filecodebox
56+
rm -rf build/
5157
go clean
5258

5359
# 整理依赖
@@ -94,6 +100,7 @@ help:
94100
@echo "可用的make命令:"
95101
@echo " build - 编译项目(带版本信息)"
96102
@echo " release - 发布构建(优化编译)"
103+
@echo " release-all - 多平台发布构建"
97104
@echo " run - 编译并运行项目"
98105
@echo " version - 显示版本信息"
99106
@echo " test - 运行测试"

build-release.sh

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
#!/bin/bash
2+
3+
# 多平台构建脚本
4+
# 用于本地测试构建或手动发布
5+
6+
set -e
7+
8+
# 版本信息
9+
VERSION=${1:-"dev-$(git rev-parse --short HEAD)"}
10+
COMMIT=$(git rev-parse HEAD)
11+
DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
12+
13+
# 构建标志
14+
LDFLAGS="-s -w -X main.version=${VERSION} -X main.commit=${COMMIT} -X main.date=${DATE}"
15+
16+
# 创建构建目录
17+
BUILD_DIR="build"
18+
rm -rf ${BUILD_DIR}
19+
mkdir -p ${BUILD_DIR}
20+
21+
echo "🚀 开始构建 FileCodeBox ${VERSION}"
22+
echo "📅 构建时间: ${DATE}"
23+
echo "📝 提交哈希: ${COMMIT}"
24+
echo ""
25+
26+
# 定义平台列表
27+
declare -a platforms=(
28+
"linux/amd64"
29+
"linux/arm64"
30+
"darwin/amd64"
31+
"darwin/arm64"
32+
"windows/amd64"
33+
"windows/arm64"
34+
)
35+
36+
# 构建每个平台
37+
for platform in "${platforms[@]}"; do
38+
IFS='/' read -r -a platform_split <<< "$platform"
39+
GOOS="${platform_split[0]}"
40+
GOARCH="${platform_split[1]}"
41+
42+
# 确定输出文件名
43+
output_name="filecodebox-${GOOS}-${GOARCH}"
44+
if [ "$GOOS" = "windows" ]; then
45+
output_name="${output_name}.exe"
46+
fi
47+
48+
echo "🔨 构建 ${GOOS}/${GOARCH} -> ${output_name}"
49+
50+
# 构建二进制文件
51+
CGO_ENABLED=0 GOOS=$GOOS GOARCH=$GOARCH go build \
52+
-ldflags="${LDFLAGS}" \
53+
-o "${BUILD_DIR}/${output_name}" .
54+
55+
# 设置执行权限 (非 Windows)
56+
if [ "$GOOS" != "windows" ]; then
57+
chmod +x "${BUILD_DIR}/${output_name}"
58+
fi
59+
60+
# 创建发布包目录
61+
package_dir="${BUILD_DIR}/package-${GOOS}-${GOARCH}"
62+
mkdir -p "$package_dir"
63+
64+
# 复制可执行文件
65+
cp "${BUILD_DIR}/${output_name}" "$package_dir/"
66+
67+
# 创建 README
68+
cat > "$package_dir/README.txt" << EOF
69+
FileCodeBox - 文件分享服务
70+
71+
平台: ${GOOS}/${GOARCH}
72+
版本: ${VERSION}
73+
构建时间: ${DATE}
74+
Git 提交: ${COMMIT}
75+
76+
使用方法:
77+
1. 运行可执行文件启动服务
78+
2. 访问 http://localhost:12345
79+
3. 管理员访问 http://localhost:12345/admin
80+
4. 默认管理员密码: FileCodeBox2025
81+
82+
配置文件会在首次运行时自动创建。
83+
84+
更多信息: https://github.com/zy84338719/FileCodeBox
85+
EOF
86+
87+
# 创建启动脚本 (非 Windows)
88+
if [ "$GOOS" != "windows" ]; then
89+
cat > "$package_dir/start.sh" << 'EOF'
90+
#!/bin/bash
91+
echo "🚀 启动 FileCodeBox..."
92+
echo "📱 用户界面: http://localhost:12345"
93+
echo "⚙️ 管理界面: http://localhost:12345/admin"
94+
echo "🔑 默认密码: FileCodeBox2025"
95+
echo ""
96+
echo "按 Ctrl+C 停止服务"
97+
echo ""
98+
./$(basename "$package_dir" | sed 's/filecodebox-/filecodebox-/' | cut -d'-' -f1-3)
99+
EOF
100+
chmod +x "$package_dir/start.sh"
101+
else
102+
# Windows 批处理文件
103+
cat > "$package_dir/start.bat" << 'EOF'
104+
@echo off
105+
echo 🚀 启动 FileCodeBox...
106+
echo 📱 用户界面: http://localhost:12345
107+
echo ⚙️ 管理界面: http://localhost:12345/admin
108+
echo 🔑 默认密码: FileCodeBox2025
109+
echo.
110+
echo 按 Ctrl+C 停止服务
111+
echo.
112+
filecodebox-windows-amd64.exe
113+
pause
114+
EOF
115+
fi
116+
117+
# 打包
118+
cd "${BUILD_DIR}"
119+
package_name="filecodebox-${GOOS}-${GOARCH}"
120+
if [ "$GOOS" = "windows" ]; then
121+
zip -r "${package_name}.zip" "package-${GOOS}-${GOARCH}/"
122+
echo "📦 已创建: ${package_name}.zip"
123+
else
124+
tar -czf "${package_name}.tar.gz" "package-${GOOS}-${GOARCH}/"
125+
echo "📦 已创建: ${package_name}.tar.gz"
126+
fi
127+
cd ..
128+
129+
# 清理临时目录
130+
rm -rf "$package_dir"
131+
132+
echo "${GOOS}/${GOARCH} 构建完成"
133+
echo ""
134+
done
135+
136+
echo "🎉 所有平台构建完成!"
137+
echo ""
138+
echo "📁 构建文件位置: ${BUILD_DIR}/"
139+
ls -lh ${BUILD_DIR}/
140+
141+
echo ""
142+
echo "📋 构建摘要:"
143+
echo "版本: ${VERSION}"
144+
echo "平台数量: ${#platforms[@]}"
145+
echo "构建时间: ${DATE}"
146+
147+
# 计算文件大小
148+
total_size=$(du -sh ${BUILD_DIR} | cut -f1)
149+
echo "总大小: ${total_size}"
150+
151+
echo ""
152+
echo "🚀 测试本地构建:"
153+
echo " ./build/filecodebox-$(go env GOOS)-$(go env GOARCH)$(if [ '$(go env GOOS)' = 'windows' ]; then echo '.exe'; fi)"

internal/mcp/filecodebox.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -332,10 +332,10 @@ func (f *FileCodeBoxMCPServer) handleGetShare(ctx context.Context, arguments map
332332
info.WriteString(fmt.Sprintf("使用次数:%d/%d\n", fileCode.UsedCount, fileCode.ExpiredCount))
333333

334334
if fileCode.Text != "" {
335-
info.WriteString(fmt.Sprintf("类型:文本\n"))
335+
info.WriteString("类型:文本\n")
336336
info.WriteString(fmt.Sprintf("内容:%s\n", fileCode.Text))
337337
} else {
338-
info.WriteString(fmt.Sprintf("类型:文件\n"))
338+
info.WriteString("类型:文件\n")
339339
info.WriteString(fmt.Sprintf("文件名:%s%s\n", fileCode.Prefix, fileCode.Suffix))
340340
info.WriteString(fmt.Sprintf("文件大小:%d 字节\n", fileCode.Size))
341341
}
@@ -501,10 +501,10 @@ func (f *FileCodeBoxMCPServer) handleGetStorageInfo(ctx context.Context, argumen
501501

502502
// 测试存储连接
503503
if err := f.storageManager.TestStorage(f.config.FileStorage); err != nil {
504-
info.WriteString(fmt.Sprintf("存储状态:不可用\n"))
504+
info.WriteString("存储状态:不可用\n")
505505
info.WriteString(fmt.Sprintf("错误信息:%s\n", err.Error()))
506506
} else {
507-
info.WriteString(fmt.Sprintf("存储状态:可用\n"))
507+
info.WriteString("存储状态:可用\n")
508508
}
509509

510510
info.WriteString("\n=== 支持的存储类型 ===\n")
@@ -654,7 +654,7 @@ func (f *FileCodeBoxMCPServer) readStatusResource(ctx context.Context, uri strin
654654

655655
status := map[string]interface{}{
656656
"timestamp": time.Now().Format(time.RFC3339),
657-
"server_info": f.Server.info,
657+
"server_info": f.info,
658658
"system_stats": stats,
659659
"storage_type": f.config.FileStorage,
660660
"user_system": f.config.EnableUserSystem,

internal/mcp/manager.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,12 @@ func (m *MCPManager) testMCPConnection(port string) bool {
206206
if err != nil {
207207
return false
208208
}
209-
defer conn.Close()
209+
defer func() {
210+
if err := conn.Close(); err != nil {
211+
// 在这种测试场景下,关闭连接的错误不是关键问题,只记录一下
212+
fmt.Printf("Warning: failed to close connection: %v\n", err)
213+
}
214+
}()
210215

211216
// 简单的连接测试,如果能连接就认为服务器在运行
212217
return true

internal/mcp/server.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,11 @@ func (s *Server) ServeTCP(addr string) error {
135135
if err != nil {
136136
return fmt.Errorf("failed to listen on %s: %w", addr, err)
137137
}
138-
defer listener.Close()
138+
defer func() {
139+
if err := listener.Close(); err != nil {
140+
s.logger.Errorf("Failed to close listener: %v", err)
141+
}
142+
}()
139143

140144
for {
141145
conn, err := listener.Accept()
@@ -150,7 +154,11 @@ func (s *Server) ServeTCP(addr string) error {
150154

151155
// handleTCPConnection 处理 TCP 连接
152156
func (s *Server) handleTCPConnection(tcpConn net.Conn) {
153-
defer tcpConn.Close()
157+
defer func() {
158+
if err := tcpConn.Close(); err != nil {
159+
s.logger.Errorf("Failed to close TCP connection: %v", err)
160+
}
161+
}()
154162

155163
ctx, cancel := context.WithCancel(context.Background())
156164
defer cancel()
@@ -201,7 +209,9 @@ func (s *Server) handleConnection(conn *Connection) error {
201209
var msg JSONRPCMessage
202210
if err := json.Unmarshal([]byte(line), &msg); err != nil {
203211
s.logger.Errorf("Failed to parse JSON-RPC message: %v", err)
204-
s.sendError(conn, nil, ParseError, "Parse error", nil)
212+
if err := s.sendError(conn, nil, ParseError, "Parse error", nil); err != nil {
213+
s.logger.Errorf("Failed to send error response: %v", err)
214+
}
205215
continue
206216
}
207217

0 commit comments

Comments
 (0)