[FEAT] 新增全域 workflow 指令入口
1. 新增 ./workflow 統一執行器,支援 load-ids、daily-work-log、hotfix-prod、demo-day-pptx、start-task、promote-env、monthly-report、now-push。 2. 補充 docs/workflow-commands.md 使用說明與參數範例,便於團隊直接操作。
This commit is contained in:
parent
da11241f72
commit
7766fce1d4
44
docs/workflow-commands.md
Normal file
44
docs/workflow-commands.md
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# Workflow Commands
|
||||||
|
|
||||||
|
統一入口:`./workflow`
|
||||||
|
|
||||||
|
## 查看可用指令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./workflow list
|
||||||
|
```
|
||||||
|
|
||||||
|
## 執行指令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./workflow run <name> [args...]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 指令對照
|
||||||
|
|
||||||
|
- `load-ids`
|
||||||
|
- 載入 `~/.gemini/AGENTS.md` 與 `~/.gemini/GEMINI.md` 內容。
|
||||||
|
|
||||||
|
- `daily-work-log`
|
||||||
|
- 輸出今日 commit:`git log --since="midnight" ...`
|
||||||
|
|
||||||
|
- `hotfix-prod <hotfix-name>`
|
||||||
|
- 從 `main` 建立 `hotfix/<name>`。
|
||||||
|
|
||||||
|
- `demo-day-pptx`
|
||||||
|
- 輸出流程提醒(先做 implementation_plan 再做 PPTX)。
|
||||||
|
|
||||||
|
- `start-task <feat|fix|refactor|docs> <task-name-kebab> [--stash]`
|
||||||
|
- 從最新 `dev` 建立任務分支,必要時先 stash 再 pop。
|
||||||
|
|
||||||
|
- `promote-env <dev|demo> <demo|main> [--force-main]`
|
||||||
|
- 支援 `dev -> demo` 或 `demo -> main`。
|
||||||
|
- 會先列出 log 與敏感檔案,再 merge/push,最後切回 `dev`。
|
||||||
|
|
||||||
|
- `monthly-report <year> <month>`
|
||||||
|
- 產生月報草稿檔案:`docs/monthly-report-YYYY-MM.md`。
|
||||||
|
|
||||||
|
- `now-push <target-branch> <prefix> "<summary>" ["detail1" ...]`
|
||||||
|
- `prefix`: `FIX|FEAT|DOCS|STYLE|REFACTOR`
|
||||||
|
- 自動 `git add -A`、commit、push 到目標分支。
|
||||||
|
|
||||||
218
workflow
Executable file
218
workflow
Executable file
@ -0,0 +1,218 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
WF_DIR="${HOME}/.gemini/config/global_workflows"
|
||||||
|
SELF_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
Usage:
|
||||||
|
./workflow list
|
||||||
|
./workflow run <name> [args...]
|
||||||
|
|
||||||
|
Workflows:
|
||||||
|
load-ids
|
||||||
|
daily-work-log
|
||||||
|
hotfix-prod <hotfix-name>
|
||||||
|
demo-day-pptx
|
||||||
|
start-task <feat|fix|refactor|docs> <task-name-kebab> [--stash]
|
||||||
|
promote-env <dev|demo> <demo|main> [--force-main]
|
||||||
|
monthly-report <year> <month>
|
||||||
|
now-push <target-branch> <prefix:FIX|FEAT|DOCS|STYLE|REFACTOR> "<summary>" ["detail 1" "detail 2"...]
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
require_repo() {
|
||||||
|
git -C "${SELF_DIR}" rev-parse --is-inside-work-tree >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_dev_window_for_main() {
|
||||||
|
local now_dow now_hm
|
||||||
|
now_dow="$(date +%u)" # 1..7 = Mon..Sun
|
||||||
|
now_hm="$(date +%H%M)"
|
||||||
|
if [[ "${now_dow}" -gt 4 || "${now_hm}" -gt 1200 ]]; then
|
||||||
|
echo "WARNING: 現在不在標準上線時段(週一至週四 12:00 前)。"
|
||||||
|
if [[ "${1:-}" != "--force-main" ]]; then
|
||||||
|
echo "中止。若確認要繼續,請加上 --force-main。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_list() {
|
||||||
|
ls -1 "${WF_DIR}" 2>/dev/null | sed 's/\.md$//'
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_load_ids() {
|
||||||
|
sed -n '1,120p' "${HOME}/.gemini/AGENTS.md"
|
||||||
|
echo
|
||||||
|
sed -n '1,120p' "${HOME}/.gemini/GEMINI.md"
|
||||||
|
echo
|
||||||
|
echo "身份與全域規範已加載完成。"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_daily_work_log() {
|
||||||
|
require_repo
|
||||||
|
git -C "${SELF_DIR}" log --since="midnight" --pretty=format:"%h - %s (%an)"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_hotfix_prod() {
|
||||||
|
require_repo
|
||||||
|
local name="${1:-}"
|
||||||
|
if [[ -z "${name}" ]]; then
|
||||||
|
echo "hotfix-prod 需要 hotfix 名稱。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
git -C "${SELF_DIR}" checkout main
|
||||||
|
git -C "${SELF_DIR}" pull origin main
|
||||||
|
git -C "${SELF_DIR}" checkout -b "hotfix/${name}"
|
||||||
|
echo "已建立分支 hotfix/${name}。完成修復後請自行合併到 main,再回補 demo/dev。"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_demo_day_pptx() {
|
||||||
|
cat <<'EOF'
|
||||||
|
demo-day-pptx 已觸發:
|
||||||
|
1) 先產出 implementation_plan.md(7-9頁)給你確認
|
||||||
|
2) 確認後再執行 PPTX 產製
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_start_task() {
|
||||||
|
require_repo
|
||||||
|
local kind="${1:-}" name="${2:-}" stash_opt="${3:-}"
|
||||||
|
if [[ ! "${kind}" =~ ^(feat|fix|refactor|docs)$ ]] || [[ -z "${name}" ]]; then
|
||||||
|
echo "用法:./workflow run start-task <feat|fix|refactor|docs> <task-name-kebab> [--stash]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$(git -C "${SELF_DIR}" status --porcelain)" && "${stash_opt}" == "--stash" ]]; then
|
||||||
|
git -C "${SELF_DIR}" stash push -u -m "workflow:start-task"
|
||||||
|
fi
|
||||||
|
|
||||||
|
git -C "${SELF_DIR}" checkout dev
|
||||||
|
git -C "${SELF_DIR}" pull origin dev
|
||||||
|
git -C "${SELF_DIR}" checkout -b "${kind}/${name}"
|
||||||
|
|
||||||
|
if git -C "${SELF_DIR}" stash list | rg -q "workflow:start-task"; then
|
||||||
|
git -C "${SELF_DIR}" stash pop || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "已切到分支 ${kind}/${name}"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_promote_env() {
|
||||||
|
require_repo
|
||||||
|
local src="${1:-}" dst="${2:-}" force_main="${3:-}"
|
||||||
|
if [[ -z "${src}" || -z "${dst}" ]]; then
|
||||||
|
echo "用法:./workflow run promote-env <dev|demo> <demo|main> [--force-main]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ "${src}" == "dev" && "${dst}" != "demo" ]]; then
|
||||||
|
echo "僅允許 dev -> demo。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ "${src}" == "demo" && "${dst}" != "main" ]]; then
|
||||||
|
echo "僅允許 demo -> main。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ "${dst}" == "main" ]]; then
|
||||||
|
ensure_dev_window_for_main "${force_main:-}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== 待晉升提交 ==="
|
||||||
|
git -C "${SELF_DIR}" log "${dst}..${src}" --oneline || true
|
||||||
|
echo
|
||||||
|
echo "=== 敏感檔案檢查 ==="
|
||||||
|
git -C "${SELF_DIR}" diff --name-only "${dst}...${src}" | rg "^(database/migrations/|\.env\.example|rbac-rules\.md)" || true
|
||||||
|
|
||||||
|
git -C "${SELF_DIR}" checkout "${dst}"
|
||||||
|
git -C "${SELF_DIR}" pull origin "${dst}"
|
||||||
|
git -C "${SELF_DIR}" merge "${src}" --no-ff -m "[PROMOTE] ${src} -> ${dst}"
|
||||||
|
git -C "${SELF_DIR}" push origin "${dst}"
|
||||||
|
git -C "${SELF_DIR}" checkout dev
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_monthly_report() {
|
||||||
|
local year="${1:-}" month="${2:-}"
|
||||||
|
if [[ ! "${year}" =~ ^[0-9]{4}$ ]] || [[ ! "${month}" =~ ^[0-9]{1,2}$ ]]; then
|
||||||
|
echo "用法:./workflow run monthly-report <year> <month>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
local out="${SELF_DIR}/docs/monthly-report-${year}-$(printf "%02d" "${month}").md"
|
||||||
|
mkdir -p "${SELF_DIR}/docs"
|
||||||
|
cat > "${out}" <<EOF
|
||||||
|
# Monthly Report Draft (${year}-$(printf "%02d" "${month}"))
|
||||||
|
|
||||||
|
## Data Source
|
||||||
|
- Notion Work Log (to be fetched)
|
||||||
|
- Git commits for the target month
|
||||||
|
|
||||||
|
## Slide Plan
|
||||||
|
1. 封面與概要
|
||||||
|
2. 月初至月底時序成果
|
||||||
|
3. 關鍵技術專題
|
||||||
|
4. 下月展望
|
||||||
|
EOF
|
||||||
|
echo "已建立草稿:${out}"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_now_push() {
|
||||||
|
require_repo
|
||||||
|
local target="${1:-}" prefix="${2:-}" summary="${3:-}"
|
||||||
|
shift 3 || true
|
||||||
|
if [[ -z "${target}" || -z "${prefix}" || -z "${summary}" ]]; then
|
||||||
|
echo '用法:./workflow run now-push <target-branch> <prefix:FIX|FEAT|DOCS|STYLE|REFACTOR> "<summary>" ["detail 1" ...]'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local p="[${prefix}]"
|
||||||
|
if [[ ! "${p}" =~ ^\[(FIX|FEAT|DOCS|STYLE|REFACTOR)\]$ ]]; then
|
||||||
|
echo "prefix 僅能為 FIX/FEAT/DOCS/STYLE/REFACTOR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${target}" == "main" ]]; then
|
||||||
|
ensure_dev_window_for_main "${4:-}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local msg="${p} ${summary}"
|
||||||
|
if [[ "$#" -gt 0 ]]; then
|
||||||
|
msg+=$'\n\n'
|
||||||
|
local i=1
|
||||||
|
for item in "$@"; do
|
||||||
|
msg+="${i}. ${item}"$'\n'
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
git -C "${SELF_DIR}" add -A
|
||||||
|
git -C "${SELF_DIR}" commit -m "${msg}"
|
||||||
|
local cur
|
||||||
|
cur="$(git -C "${SELF_DIR}" branch --show-current)"
|
||||||
|
git -C "${SELF_DIR}" push origin "${cur}:${target}"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local action="${1:-}"
|
||||||
|
case "${action}" in
|
||||||
|
list) cmd_list ;;
|
||||||
|
run)
|
||||||
|
local name="${2:-}"
|
||||||
|
shift 2 || true
|
||||||
|
case "${name}" in
|
||||||
|
load-ids) cmd_load_ids "$@" ;;
|
||||||
|
daily-work-log) cmd_daily_work_log "$@" ;;
|
||||||
|
hotfix-prod) cmd_hotfix_prod "$@" ;;
|
||||||
|
demo-day-pptx) cmd_demo_day_pptx "$@" ;;
|
||||||
|
start-task) cmd_start_task "$@" ;;
|
||||||
|
promote-env) cmd_promote_env "$@" ;;
|
||||||
|
monthly-report) cmd_monthly_report "$@" ;;
|
||||||
|
now-push) cmd_now_push "$@" ;;
|
||||||
|
*) usage; exit 1 ;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*) usage; exit 1 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
Loading…
Reference in New Issue
Block a user