feat: add build_script

This commit is contained in:
2025-10-22 11:40:12 +08:00
parent d80f88dbb4
commit 78b6f9e6c5
6 changed files with 491 additions and 2 deletions
+46
View File
@@ -0,0 +1,46 @@
.PHONY: image tag version
# 默认架构
GOOS ?= linux
GOARCH ?= $(shell go env GOARCH)
# 常用架构组合
PLATFORMS ?= linux/amd64,linux/arm64
# Docker 构建
docker-local:
$(MAKE) check-image-name
GOOS=$(GOOS) GOARCH=$(GOARCH) .build_scripts/build_go.sh
GOOS=$(GOOS) GOARCH=$(GOARCH) .build_scripts/build_image.sh $(IMAGE_NAME) Dockerfile.local
docker-local-amd64:
$(MAKE) check-image-name
GOOS=linux GOARCH=amd64 .build_scripts/build_go.sh
GOOS=linux GOARCH=amd64 .build_scripts/build_image.sh $(IMAGE_NAME) Dockerfile.local
docker-local-arm64:
$(MAKE) check-image-name
GOOS=linux GOARCH=arm64 .build_scripts/build_go.sh
GOOS=linux GOARCH=arm64 .build_scripts/build_image.sh $(IMAGE_NAME) Dockerfile.local
docker-local-multiarch:
$(MAKE) check-image-name
make build-all-multiarch
PLATFORM=$(PLATFORMS) .build_scripts/build_image.sh $(IMAGE_NAME) Dockerfile.local
check-image-name:
@if [ -z "$(IMAGE_NAME)" ]; then \
echo "IMAGE_NAME is not set"; \
exit 1; \
fi; \
tag:
@VERSION=$$(cat VERSION); \
echo "Creating tag: $$VERSION"; \
git tag $$VERSION; \
git push origin $$VERSION; \
echo "Tag $$VERSION created and pushed successfully"
version: .build_scripts/version.sh
@.build_scripts/version.sh "$(filter-out version,$(MAKECMDGOALS))" "$(VERSION)"
+250
View File
@@ -0,0 +1,250 @@
# Scripts 使用说明
这个目录包含项目的构建和版本管理脚本。
## 文件说明
- `Makefile`: 构建、推送 Docker 镜像和版本管理的自动化脚本
- `version.sh`: 版本号管理脚本
## Makefile 使用
### 可配置的环境变量
- `IMAGE_NAME`: Docker 镜像名称
### 独立使用
#### 1. 使用默认镜像名
```bash
cd scripts
make image
```
#### 2. 使用自定义镜像名
```bash
cd scripts
IMAGE_NAME=myregistry/myimage make image
```
或者:
```bash
export IMAGE_NAME=myregistry/myimage
cd scripts
make image
```
### 在其他 Makefile 中引用
有多种方式可以在其他 Makefile 中引用这个 Makefile:
#### 方式一:使用 `$(MAKE) -C` 调用子目录(推荐)
在项目根目录创建主 Makefile:
```makefile
.PHONY: build-image
# 定义镜像名称
IMAGE_NAME = myregistry/myproject
# 调用 scripts 目录下的 Makefile
build-image:
IMAGE_NAME=$(IMAGE_NAME) $(MAKE) -C scripts image
# 或者使用 export 导出环境变量
build-image-export:
export IMAGE_NAME=$(IMAGE_NAME) && $(MAKE) -C scripts image
```
使用:
```bash
make build-image
```
#### 方式二:使用 `include` 包含
在项目根目录的 Makefile 中:
```makefile
# 设置变量(会覆盖被包含文件中的默认值)
IMAGE_NAME = myregistry/myproject
# 包含 scripts 目录的 Makefile
include scripts/Makefile
# 现在可以直接调用 image 目标
.PHONY: build
build: image
```
使用:
```bash
make build
```
**注意**: 使用 `include` 时,相对路径会基于主 Makefile 的位置,可能需要调整路径。
#### 方式三:环境变量传递(跨多层 Makefile)
根目录 `Makefile`:
```makefile
.PHONY: all
# 设置并导出环境变量,使所有子 make 都能访问
export IMAGE_NAME = myregistry/myproject
export VERSION = v1.0.0
all:
@echo "Building with IMAGE_NAME=$(IMAGE_NAME)"
$(MAKE) -C scripts image
```
#### 方式四:通过命令行传递多个变量
```bash
IMAGE_NAME=myregistry/myimage VERSION=v2.0.0 make -C scripts image
```
### 完整示例
假设项目结构:
```
/project-root
├── Makefile # 主 Makefile
├── scripts/
│ ├── Makefile # 本文件
│ └── version.sh
└── ...
```
主 `Makefile` 内容示例:
```makefile
.PHONY: help build-backend build-frontend build-all
# 项目配置
PROJECT_NAME = myproject
REGISTRY = docker.io/myorg
BACKEND_IMAGE = $(REGISTRY)/$(PROJECT_NAME)-backend
FRONTEND_IMAGE = $(REGISTRY)/$(PROJECT_NAME)-frontend
help:
@echo "Available targets:"
@echo " build-backend - Build and push backend image"
@echo " build-frontend - Build and push frontend image"
@echo " build-all - Build and push all images"
build-backend:
@echo "Building backend image..."
IMAGE_NAME=$(BACKEND_IMAGE) $(MAKE) -C scripts image
build-frontend:
@echo "Building frontend image..."
IMAGE_NAME=$(FRONTEND_IMAGE) $(MAKE) -C scripts image
build-all: build-backend build-frontend
@echo "All images built successfully!"
# 也可以创建版本管理的快捷方式
version:
$(MAKE) -C scripts version $(filter-out $@,$(MAKECMDGOALS))
# 允许传递额外参数
%:
@:
```
使用示例:
```bash
# 构建后端镜像
make build-backend
# 构建前端镜像
make build-frontend
# 构建所有镜像
make build-all
# 版本管理
make version patch
make version v1.2.3
```
## 版本管理
### 基本用法
```bash
# 查看当前版本和帮助
make version
# 设置特定版本
make version v1.0.0
# 或者
make version VERSION=v1.0.0
# 递增版本
make version patch # v1.0.0 -> v1.0.1
make version minor # v1.0.0 -> v1.1.0
make version major # v1.0.0 -> v2.0.0
# 预发布版本
make version pre # v1.0.0 -> v1.0.0-rc.1
make version pre alpha # v1.0.0 -> v1.0.0-alpha.1
make version pre beta # v1.0.0 -> v1.0.0-beta.1
make version pre rc 2 # v1.0.0 -> v1.0.0-rc.2
```
## 创建标签
```bash
# 基于 VERSION 文件创建并推送 Git 标签
make tag
```
## 注意事项
1. **环境变量优先级**:
- 命令行传递 > 父 Makefile export > 本 Makefile 默认值
2. **工作目录**:
- 使用 `$(MAKE) -C scripts` 会切换到 scripts 目录执行
- 注意脚本中的相对路径问题
3. **变量传递**:
- `IMAGE_NAME=xxx $(MAKE)`: 只对当前 make 有效
- `export IMAGE_NAME=xxx; $(MAKE)`: 对所有子 make 有效
- `export IMAGE_NAME=xxx` 后再调用: 对整个 shell 会话有效
4. **调试技巧**:
```bash
# 查看实际使用的变量值
make -C scripts image -n # 干运行,只显示命令不执行
```
## 扩展建议
如果需要更复杂的配置,可以创建配置文件:
```makefile
# config.mk
PROJECT_NAME = myproject
REGISTRY = docker.io/myorg
VERSION = v1.0.0
# 在主 Makefile 中
include config.mk
export IMAGE_NAME = $(REGISTRY)/$(PROJECT_NAME)
```
这样可以将配置集中管理,便于维护。
+12
View File
@@ -0,0 +1,12 @@
#!/bin/bash
# Build Go binary
# Args:
# 1. OUTPUT_DIR: output directory, default is ./output, the full output directory is $OUTPUT_DIR/$GOOS-$GOARCH
set -e
OUTPUT_DIR=${1:-./output}
mkdir -p $OUTPUT_DIR/$GOOS-$GOARCH
go build -o $OUTPUT_DIR/$GOOS-$GOARCH/server ./cmd/
+30
View File
@@ -0,0 +1,30 @@
#!/bin/bash
# Build Docker image
# Args:
# 1. IMAGE_NAME: image name, required
# 2. DOCKER_FILE: docker file, default is Dockerfile
set -e
IMAGE_NAME=$1
DOCKER_FILE=${2:-Dockerfile}
if [ -z "$IMAGE_NAME" ]; then
echo "IMAGE_NAME is not set";
exit 1;
fi;
VERSION=$(cat VERSION);
echo "Building image: $IMAGE_NAME:$VERSION with Dockerfile: $DOCKER_FILE";
docker build -t $IMAGE_NAME:$VERSION -f $DOCKER_FILE .;
docker push $IMAGE_NAME:$VERSION;
if [[ "$VERSION" != *"-"* ]]; then
echo "This is a stable release, also tagging as latest";
docker tag $IMAGE_NAME:$VERSION $IMAGE_NAME:latest;
docker push $IMAGE_NAME:latest;
echo "Latest tag pushed successfully";
else
echo "This is a pre-release version, skipping latest tag";
fi;
echo "Image built and pushed successfully: $IMAGE_NAME:$VERSION"
+152
View File
@@ -0,0 +1,152 @@
#!/bin/bash
# Version management script
# Args:
# 1. ARGS: arguments, optional
# 2. VERSION_VAR: version variable, optional
set -e
ARGS="$1"
VERSION_VAR="$2"
CURRENT_VERSION=$(cat VERSION)
show_usage() {
echo "Current version: $CURRENT_VERSION"
echo "Usage:"
echo " make version VERSION=v1.0.0 # Set specific version"
echo " make version v1.0.0 # Set specific version"
echo " make version patch # Increment patch version"
echo " make version minor # Increment minor version"
echo " make version major # Increment major version"
echo " make version pre # Add/increment pre-release (default: rc)"
echo " make version pre alpha # Add alpha pre-release"
echo " make version pre beta # Add beta pre-release"
echo " make version pre rc # Add rc pre-release"
echo " make version pre alpha 2 # Add specific alpha version"
}
parse_version() {
local version="$1"
# Remove 'v' prefix and split by '-'
local clean_version="${version#v}"
local base_version="${clean_version%-*}"
local pre_release=""
if [[ "$clean_version" == *"-"* ]]; then
pre_release="${clean_version#*-}"
fi
# Split base version
IFS='.' read -r major minor patch <<< "$base_version"
echo "$major $minor $patch $pre_release"
}
increment_version() {
local type="$1"
local version_parts
read -r major minor patch pre_release <<< "$(parse_version "$CURRENT_VERSION")"
case "$type" in
"patch")
patch=$((patch + 1))
echo "v$major.$minor.$patch"
;;
"minor")
minor=$((minor + 1))
patch=0
echo "v$major.$minor.$patch"
;;
"major")
major=$((major + 1))
minor=0
patch=0
echo "v$major.$minor.$patch"
;;
esac
}
handle_prerelease() {
local args=($1)
local version_parts
read -r major minor patch pre_release <<< "$(parse_version "$CURRENT_VERSION")"
local base_version="$major.$minor.$patch"
local pre_type="rc"
local pre_num="1"
# Parse arguments
if [[ ${#args[@]} -ge 3 ]]; then
# make version pre alpha 2 (明确指定版本号)
pre_type="${args[1]}"
pre_num="${args[2]}"
elif [[ ${#args[@]} -ge 2 ]]; then
# make version pre alpha (指定类型,智能处理版本号)
pre_type="${args[1]}"
if [[ -n "$pre_release" ]]; then
# 当前已经是 pre-release
IFS='.' read -r current_type current_num <<< "$pre_release"
if [[ "$current_type" == "$pre_type" ]]; then
# 相同类型,递增版本号
pre_num=$((current_num + 1))
else
# 不同类型,重置为 1
pre_num="1"
fi
else
# 当前是正式版本,从 1 开始
pre_num="1"
fi
else
# make version pre (智能处理)
if [[ -n "$pre_release" ]]; then
# 当前已经是 pre-release,递增版本号
IFS='.' read -r current_type current_num <<< "$pre_release"
pre_type="$current_type"
pre_num=$((current_num + 1))
else
# 当前是正式版本,添加默认 pre-release
pre_type="rc"
pre_num="1"
fi
fi
echo "v$base_version-$pre_type.$pre_num"
}
update_version() {
local new_version="$1"
echo "Updating version from $CURRENT_VERSION to $new_version"
echo "$new_version" > VERSION
git add .
git commit -m "update version to $new_version"
git push origin HEAD
echo "[$new_version] Version file updated and pushed successfully"
}
main() {
if [[ -n "$ARGS" ]]; then
local first_arg="${ARGS%% *}"
case "$first_arg" in
"patch"|"minor"|"major")
new_version=$(increment_version "$first_arg")
;;
"pre")
new_version=$(handle_prerelease "$ARGS")
;;
*)
new_version="$first_arg"
;;
esac
update_version "$new_version"
elif [[ -n "$VERSION_VAR" ]]; then
update_version "$VERSION_VAR"
else
show_usage
fi
}
main "$@"