mirror of
https://ghfast.top/https://github.com/aeroxw/tick-stock-panel.git
synced 2026-09-12 14:24:15 +08:00
ci(docker): 优化镜像构建工作流 + 清理未启用的版本自增脚本
在 #22 (Docker 镜像构建工作流) 基础上的三点优化: 1. CI 关闭国内镜像源(USE_CN_MIRROR=0): GitHub runner 在海外, 让构建直连官方 npm/PyPI 反而更快更稳; 本地/国内手动 docker build 仍走 Dockerfile 默认的 CN 镜像。 2. 新增 .dockerignore: 排除 .git/data/node_modules/docs/screenshots 等 非构建必需文件, 减小上下文体积、加速传输。 3. 叠加 tag 触发 + build-push-action v5→v6: 打 v* tag 时额外产出 带版本号镜像(如 :v0.1.62), 便于固定回溯。 清理: - 删除 scripts/bump_version.py (prepare-commit-msg hook 从未实际安装, 属于死代码; 发版版本号改为手动维护, 与方案 B 一致)。 - 同步修正 backend/app/api/data.py 中对该脚本的过时引用注释。
This commit is contained in:
@@ -0,0 +1,57 @@
|
|||||||
|
# 构建 Docker 镜像时排除的文件 / 目录。
|
||||||
|
# 与 .gitignore 思路一致: 只把 Dockerfile 真正需要的送进构建上下文,
|
||||||
|
# 减小上下文体积、加速上传、避免缓存误伤。
|
||||||
|
# 注意: .dockerignore 不识别 .gitignore 的取反(!)语法, 这里按白名单思路直接列举排除项。
|
||||||
|
|
||||||
|
# ===== 版本控制 / CI =====
|
||||||
|
.git
|
||||||
|
.github
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# ===== 用户运行时数据(绝不应进镜像) =====
|
||||||
|
data
|
||||||
|
backend/data
|
||||||
|
|
||||||
|
# ===== 前端构建产物 / 依赖(镜像内会重新 build, 带进来反而污染) =====
|
||||||
|
frontend/node_modules
|
||||||
|
frontend/dist
|
||||||
|
backend/static
|
||||||
|
backend/app/static
|
||||||
|
|
||||||
|
# ===== Python 缓存 / 虚拟环境 =====
|
||||||
|
**/__pycache__
|
||||||
|
**/*.py[cod]
|
||||||
|
**/.pytest_cache
|
||||||
|
**/.mypy_cache
|
||||||
|
**/.ruff_cache
|
||||||
|
**/.venv
|
||||||
|
**/venv
|
||||||
|
|
||||||
|
# ===== IDE / 系统 =====
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
.DS_Store
|
||||||
|
**/*.swp
|
||||||
|
|
||||||
|
# ===== 文档 / 截图(镜像不需要; README.md 除外, Dockerfile 显式 COPY 了它) =====
|
||||||
|
docs
|
||||||
|
screenshots
|
||||||
|
|
||||||
|
# ===== 桌面客户端打包(PyInstaller 专用, 与 Docker 部署无关) =====
|
||||||
|
packaging
|
||||||
|
backend/dist
|
||||||
|
backend/build
|
||||||
|
|
||||||
|
# ===== 开发脚本(本地启服务用, 镜像不用) =====
|
||||||
|
dev.sh
|
||||||
|
dev.ps1
|
||||||
|
scripts
|
||||||
|
|
||||||
|
# ===== 密钥(防止误打进公开镜像) =====
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
backend/.env
|
||||||
|
|
||||||
|
# ===== 其他构建产物 =====
|
||||||
|
**/node_modules
|
||||||
|
*.log
|
||||||
@@ -1,8 +1,13 @@
|
|||||||
name: Build and Push Docker Image
|
name: Build and Push Docker Image
|
||||||
|
|
||||||
|
# 触发:
|
||||||
|
# - push 到 main: 覆盖刷新 :latest + :sha(每次提交可追溯)
|
||||||
|
# - 打 v* tag: 额外产出带版本号的镜像(如 :v0.1.43), 便于固定回溯
|
||||||
|
# - 手动: 网页 Actions → Run workflow
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
|
tags: ['v*']
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@@ -42,13 +47,19 @@ jobs:
|
|||||||
tags: |
|
tags: |
|
||||||
type=raw,value=latest
|
type=raw,value=latest
|
||||||
type=sha,prefix=
|
type=sha,prefix=
|
||||||
|
type=match,pattern=v*,group=0
|
||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
|
# GitHub runner 在海外, 关掉国内镜像源(USE_CN_MIRROR=0)
|
||||||
|
# 让构建直连官方 npm/PyPI, 反而更快更稳;
|
||||||
|
# 本地/国内手动 docker build 仍走 Dockerfile 默认的 CN 镜像。
|
||||||
|
build-args: |
|
||||||
|
USE_CN_MIRROR=0
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
cache-from: type=gha
|
cache-from: type=gha
|
||||||
|
|||||||
@@ -846,7 +846,7 @@ def get_version(request: Request) -> dict:
|
|||||||
"""
|
"""
|
||||||
from app import __version__
|
from app import __version__
|
||||||
|
|
||||||
# 1. 优先用 app.__version__ (开发期 bump_version.py 写入, 打包期由 PyInstaller 注入)
|
# 1. 优先用 app.__version__ (唯一权威版本, 打包期由 PyInstaller 注入)
|
||||||
if __version__:
|
if __version__:
|
||||||
v = __version__.strip()
|
v = __version__.strip()
|
||||||
return {"version": v if v.startswith("v") else f"v{v}"}
|
return {"version": v if v.startswith("v") else f"v{v}"}
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""版本号自增脚本 — 由 git prepare-commit-msg hook 调用。
|
|
||||||
|
|
||||||
读取当前版本, +0.0.1, 写回 frontend/package.json 和 backend/pyproject.toml。
|
|
||||||
跳过条件(避免 merge/rebase/amend 误触发):
|
|
||||||
- 非 master/main 分支(可选, 当前不限制)
|
|
||||||
- commit message 以 merge/squash/rebase 开头
|
|
||||||
- 环境变量 SKIP_VERSION_BUMP=1
|
|
||||||
"""
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import json
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parent.parent
|
|
||||||
PKG = ROOT / "frontend" / "package.json"
|
|
||||||
PYPROJECT = ROOT / "backend" / "pyproject.toml"
|
|
||||||
APP_INIT = ROOT / "backend" / "app" / "__init__.py" # __version__ 写在这里, health 接口读它
|
|
||||||
|
|
||||||
|
|
||||||
def parse_version(v: str) -> tuple[int, int, int]:
|
|
||||||
parts = v.strip().split(".")
|
|
||||||
while len(parts) < 3:
|
|
||||||
parts.append("0")
|
|
||||||
return int(parts[0]), int(parts[1]), int(parts[2])
|
|
||||||
|
|
||||||
|
|
||||||
def bump(v: str) -> str:
|
|
||||||
major, minor, patch = parse_version(v)
|
|
||||||
return f"{major}.{minor}.{patch + 1}"
|
|
||||||
|
|
||||||
|
|
||||||
def read_pkg_version() -> str:
|
|
||||||
data = json.loads(PKG.read_text(encoding="utf-8"))
|
|
||||||
return data["version"]
|
|
||||||
|
|
||||||
|
|
||||||
def write_pkg_version(v: str) -> None:
|
|
||||||
data = json.loads(PKG.read_text(encoding="utf-8"))
|
|
||||||
data["version"] = v
|
|
||||||
PKG.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
|
||||||
|
|
||||||
|
|
||||||
def read_pyproject_version() -> str:
|
|
||||||
text = PYPROJECT.read_text(encoding="utf-8")
|
|
||||||
m = re.search(r'^version\s*=\s*"([^"]+)"', text, re.MULTILINE)
|
|
||||||
return m.group(1) if m else "0.0.0"
|
|
||||||
|
|
||||||
|
|
||||||
def write_pyproject_version(v: str) -> None:
|
|
||||||
text = PYPROJECT.read_text(encoding="utf-8")
|
|
||||||
text = re.sub(r'^version\s*=\s*"[^"]+"', f'version = "{v}"', text, count=1, flags=re.MULTILINE)
|
|
||||||
PYPROJECT.write_text(text, encoding="utf-8")
|
|
||||||
|
|
||||||
|
|
||||||
def write_app_init_version(v: str) -> None:
|
|
||||||
"""更新 backend/app/__init__.py 的 __version__ (health 接口读这里)。"""
|
|
||||||
text = APP_INIT.read_text(encoding="utf-8")
|
|
||||||
text = re.sub(
|
|
||||||
r'^(__version__\s*=\s*)"[^"]+"',
|
|
||||||
rf'\1"{v}"',
|
|
||||||
text,
|
|
||||||
count=1,
|
|
||||||
flags=re.MULTILINE,
|
|
||||||
)
|
|
||||||
APP_INIT.write_text(text, encoding="utf-8")
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
|
||||||
# 环境变量跳过
|
|
||||||
if __import__("os").environ.get("SKIP_VERSION_BUMP") == "1":
|
|
||||||
return 0
|
|
||||||
|
|
||||||
cur = read_pkg_version()
|
|
||||||
new = bump(cur)
|
|
||||||
|
|
||||||
# 三个文件版本可能不一致, 统一用 pkg 的为准
|
|
||||||
write_pkg_version(new)
|
|
||||||
write_pyproject_version(new)
|
|
||||||
write_app_init_version(new)
|
|
||||||
|
|
||||||
# 暂存版本文件改动(并入本次 commit)
|
|
||||||
import subprocess
|
|
||||||
subprocess.run(["git", "add", str(PKG), str(PYPROJECT), str(APP_INIT)], check=True, cwd=str(ROOT))
|
|
||||||
|
|
||||||
# 输出新版本号供 hook 读用
|
|
||||||
print(f"[bump] {cur} -> {new}")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
sys.exit(main())
|
|
||||||
Reference in New Issue
Block a user