mirror of
https://github.com/woodchen-ink/random-api-go.git
synced 2025-07-18 13:52:02 +08:00
chore(workflow,ci): update docker build process and add multi-arch support
Update the GitHub Actions workflow to include Go setup, multi-arch builds, and push multi-arch Docker images. Also, refactor the CSV service to improve logging and caching mechanism.
This commit is contained in:
parent
981759be39
commit
61e84d87b8
23
.github/workflows/docker.yml
vendored
23
.github/workflows/docker.yml
vendored
@ -19,9 +19,22 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version: '1.23'
|
||||||
|
|
||||||
|
- name: Build for amd64
|
||||||
|
run: |
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -o bin/amd64/random-api .
|
||||||
|
|
||||||
|
- name: Build for arm64
|
||||||
|
run: |
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -a -installsuffix cgo -o bin/arm64/random-api .
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
@ -34,11 +47,11 @@ jobs:
|
|||||||
username: woodchen
|
username: woodchen
|
||||||
password: ${{ secrets.ACCESS_TOKEN }}
|
password: ${{ secrets.ACCESS_TOKEN }}
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push multi-arch image
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: Dockerfile
|
file: Dockerfile.run
|
||||||
push: true
|
push: true
|
||||||
tags: woodchen/${{ env.IMAGE_NAME }}:latest
|
tags: woodchen/${{ env.IMAGE_NAME }}:latest
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
@ -53,8 +66,8 @@ jobs:
|
|||||||
host: ${{ secrets.SERVER_HOST }}
|
host: ${{ secrets.SERVER_HOST }}
|
||||||
username: root
|
username: root
|
||||||
key: ${{ secrets.SERVER_SSH_KEY }}
|
key: ${{ secrets.SERVER_SSH_KEY }}
|
||||||
source: "public.zip"
|
source: 'public.zip'
|
||||||
target: "/tmp"
|
target: '/tmp'
|
||||||
|
|
||||||
- name: Execute deployment commands
|
- name: Execute deployment commands
|
||||||
uses: appleboy/ssh-action@master
|
uses: appleboy/ssh-action@master
|
||||||
|
23
Dockerfile.run
Normal file
23
Dockerfile.run
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
FROM --platform=$TARGETPLATFORM alpine:latest
|
||||||
|
|
||||||
|
WORKDIR /root/
|
||||||
|
|
||||||
|
# 安装必要的包
|
||||||
|
RUN apk --no-cache add ca-certificates tzdata tini
|
||||||
|
|
||||||
|
# 创建日志目录并设置权限
|
||||||
|
RUN mkdir -p /var/log/random-api && chmod 755 /var/log/random-api
|
||||||
|
|
||||||
|
# 根据目标平台复制对应的二进制文件
|
||||||
|
ARG TARGETARCH
|
||||||
|
COPY bin/${TARGETARCH}/random-api .
|
||||||
|
COPY public ./public
|
||||||
|
COPY public /tmp/public
|
||||||
|
COPY start.sh /start.sh
|
||||||
|
RUN chmod +x /start.sh
|
||||||
|
|
||||||
|
EXPOSE 5003
|
||||||
|
|
||||||
|
# 使用 tini 作为初始化系统
|
||||||
|
ENTRYPOINT ["/sbin/tini", "--"]
|
||||||
|
CMD ["/start.sh"]
|
@ -28,11 +28,19 @@ func InitializeCSVService() error {
|
|||||||
return fmt.Errorf("failed to load CSV paths: %v", err)
|
return fmt.Errorf("failed to load CSV paths: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 预加载所有CSV内容
|
// 获取一个CSVPathsCache的副本,避免长时间持有锁
|
||||||
Mu.RLock()
|
Mu.RLock()
|
||||||
defer Mu.RUnlock()
|
pathsCopy := make(map[string]map[string]string)
|
||||||
|
|
||||||
for prefix, suffixMap := range CSVPathsCache {
|
for prefix, suffixMap := range CSVPathsCache {
|
||||||
|
pathsCopy[prefix] = make(map[string]string)
|
||||||
|
for suffix, path := range suffixMap {
|
||||||
|
pathsCopy[prefix][suffix] = path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Mu.RUnlock()
|
||||||
|
|
||||||
|
// 使用副本进行初始化
|
||||||
|
for prefix, suffixMap := range pathsCopy {
|
||||||
for suffix, csvPath := range suffixMap {
|
for suffix, csvPath := range suffixMap {
|
||||||
selector, err := GetCSVContent(csvPath)
|
selector, err := GetCSVContent(csvPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -113,51 +121,55 @@ func LoadCSVPaths() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetCSVContent(path string) (*models.URLSelector, error) {
|
func GetCSVContent(path string) (*models.URLSelector, error) {
|
||||||
|
log.Printf("开始获取CSV内容: %s", path)
|
||||||
|
|
||||||
Mu.RLock()
|
Mu.RLock()
|
||||||
selector, exists := csvCache[path]
|
selector, exists := csvCache[path]
|
||||||
Mu.RUnlock()
|
Mu.RUnlock()
|
||||||
|
|
||||||
if exists {
|
if exists {
|
||||||
|
log.Printf("从缓存中获取到CSV内容: %s", path)
|
||||||
return selector, nil
|
return selector, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var fileContent []byte
|
var fileContent []byte
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// 获取环境变量中的基础URL
|
|
||||||
baseURL := os.Getenv(config.EnvBaseURL)
|
baseURL := os.Getenv(config.EnvBaseURL)
|
||||||
|
|
||||||
if baseURL != "" {
|
if baseURL != "" {
|
||||||
// 如果设置了基础URL,构建完整的URL
|
|
||||||
var fullURL string
|
var fullURL string
|
||||||
if strings.HasPrefix(baseURL, "http://") || strings.HasPrefix(baseURL, "https://") {
|
if strings.HasPrefix(baseURL, "http://") || strings.HasPrefix(baseURL, "https://") {
|
||||||
// 如果baseURL已经包含协议,直接使用
|
|
||||||
fullURL = utils.JoinURLPath(baseURL, path)
|
fullURL = utils.JoinURLPath(baseURL, path)
|
||||||
} else {
|
} else {
|
||||||
// 如果没有协议,添加https://
|
|
||||||
fullURL = "https://" + utils.JoinURLPath(baseURL, path)
|
fullURL = "https://" + utils.JoinURLPath(baseURL, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("尝试从URL获取: %s", fullURL)
|
log.Printf("尝试从URL获取: %s", fullURL)
|
||||||
|
|
||||||
// 创建HTTP客户端
|
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
Timeout: config.RequestTimeout,
|
Timeout: config.RequestTimeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := client.Get(fullURL)
|
resp, err := client.Get(fullURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("HTTP请求失败: %v", err)
|
||||||
return nil, fmt.Errorf("HTTP请求失败: %w", err)
|
return nil, fmt.Errorf("HTTP请求失败: %w", err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
log.Printf("HTTP请求返回非200状态码: %d", resp.StatusCode)
|
||||||
return nil, fmt.Errorf("HTTP请求返回非200状态码: %d", resp.StatusCode)
|
return nil, fmt.Errorf("HTTP请求返回非200状态码: %d", resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
fileContent, err = io.ReadAll(resp.Body)
|
fileContent, err = io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("读取响应内容失败: %v", err)
|
||||||
return nil, fmt.Errorf("读取响应内容失败: %w", err)
|
return nil, fmt.Errorf("读取响应内容失败: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("成功读取到CSV内容,长度: %d bytes", len(fileContent))
|
||||||
} else {
|
} else {
|
||||||
// 如果没有设置基础URL,从本地文件读取
|
// 如果没有设置基础URL,从本地文件读取
|
||||||
fullPath := filepath.Join("public", path)
|
fullPath := filepath.Join("public", path)
|
||||||
@ -170,6 +182,8 @@ func GetCSVContent(path string) (*models.URLSelector, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lines := strings.Split(string(fileContent), "\n")
|
lines := strings.Split(string(fileContent), "\n")
|
||||||
|
log.Printf("CSV文件包含 %d 行", len(lines))
|
||||||
|
|
||||||
uniqueURLs := make(map[string]bool)
|
uniqueURLs := make(map[string]bool)
|
||||||
var fileArray []string
|
var fileArray []string
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
@ -180,11 +194,14 @@ func GetCSVContent(path string) (*models.URLSelector, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("处理后得到 %d 个唯一URL", len(fileArray))
|
||||||
|
|
||||||
selector = models.NewURLSelector(fileArray)
|
selector = models.NewURLSelector(fileArray)
|
||||||
|
|
||||||
Mu.Lock()
|
Mu.Lock()
|
||||||
csvCache[path] = selector
|
csvCache[path] = selector
|
||||||
Mu.Unlock()
|
Mu.Unlock()
|
||||||
|
|
||||||
|
log.Printf("CSV内容已缓存: %s", path)
|
||||||
return selector, nil
|
return selector, nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user