diff --git a/.build_scripts/Makefile b/.build_scripts/Makefile new file mode 100644 index 0000000..783f6d1 --- /dev/null +++ b/.build_scripts/Makefile @@ -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)" \ No newline at end of file diff --git a/.build_scripts/README.md b/.build_scripts/README.md new file mode 100644 index 0000000..7e1f92a --- /dev/null +++ b/.build_scripts/README.md @@ -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) +``` + +这样可以将配置集中管理,便于维护。 diff --git a/.build_scripts/build_go.sh b/.build_scripts/build_go.sh new file mode 100755 index 0000000..4fae7ad --- /dev/null +++ b/.build_scripts/build_go.sh @@ -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/ \ No newline at end of file diff --git a/.build_scripts/build_image.sh b/.build_scripts/build_image.sh new file mode 100755 index 0000000..8915d98 --- /dev/null +++ b/.build_scripts/build_image.sh @@ -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" \ No newline at end of file diff --git a/.build_scripts/version.sh b/.build_scripts/version.sh new file mode 100755 index 0000000..e4b0afa --- /dev/null +++ b/.build_scripts/version.sh @@ -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 "$@" diff --git a/fish/functions/ff.fish b/fish/functions/ff.fish index b9f0516..9a07fac 100644 --- a/fish/functions/ff.fish +++ b/fish/functions/ff.fish @@ -10,7 +10,7 @@ function ff "pst|Show proxy status" \ "make|Run dotfile Makefile commands" \ "help|Show this help message" - + switch $argv[1] case reload source ~/.config/fish/config.fish @@ -70,4 +70,3 @@ function ff echo "Run 'ff help' for usage information" end end -