{"id":28411266,"url":"https://github.com/timhuang1204/issue-gantt-sync","last_synced_at":"2026-04-29T22:02:49.837Z","repository":{"id":294928817,"uuid":"988539844","full_name":"timhuang1204/issue-gantt-sync","owner":"timhuang1204","description":"將 Issue 同步到 Google Sheet 甘特圖並生成工作量報表，用於團隊資源分配分析。支援 GitLab，未來可擴展至其他平台。","archived":false,"fork":false,"pushed_at":"2026-03-20T07:46:44.000Z","size":216,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-21T00:37:00.761Z","etag":null,"topics":["gantt-chart","gitlab","google-sheets","project-managment","python","resource-management","team-management","workload-analysis"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timhuang1204.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-05-22T17:41:08.000Z","updated_at":"2026-03-20T07:46:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"41ad9a67-58e8-4137-9715-0f37d2ed600f","html_url":"https://github.com/timhuang1204/issue-gantt-sync","commit_stats":null,"previous_names":["timhuang1204/issue-gantt-sync"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/timhuang1204/issue-gantt-sync","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timhuang1204%2Fissue-gantt-sync","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timhuang1204%2Fissue-gantt-sync/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timhuang1204%2Fissue-gantt-sync/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timhuang1204%2Fissue-gantt-sync/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timhuang1204","download_url":"https://codeload.github.com/timhuang1204/issue-gantt-sync/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timhuang1204%2Fissue-gantt-sync/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32445555,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T20:22:27.477Z","status":"ssl_error","status_checked_at":"2026-04-29T20:22:26.507Z","response_time":110,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gantt-chart","gitlab","google-sheets","project-managment","python","resource-management","team-management","workload-analysis"],"created_at":"2025-06-02T15:00:31.053Z","updated_at":"2026-04-29T22:02:49.829Z","avatar_url":"https://github.com/timhuang1204.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GitLab Issue 到 Google Sheet 甘特圖同步工具\n\n[![Python Version](https://img.shields.io/badge/python-3.6%2B-blue.svg)](https://python.org)\n[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n[![Status](https://img.shields.io/badge/status-Production-brightgreen.svg)]()\n\n## 專案簡介\n\n本工具專為雲端運維團隊設計，能夠自動從 GitLab 專案中擷取 Issue 資訊，同步至 Google Sheet 並以甘特圖形式呈現，同時生成詳細的雙月工作分析報表。主要用於追蹤團隊成員在不同工作類型（VCS、VKS、VDS 等）的時間分配，協助管理層進行資源規劃與績效評估。\n\n### 核心功能\n\n- 📊 **自動化甘特圖生成**：將 GitLab Issue 轉換為視覺化時間軸\n- 📈 **樞紐分析表報表**：生成詳細的工作類型分析與趨勢比較\n- 🔄 **智能同步機制**：避免重複處理，僅同步新增 Issue\n- 👥 **多人協作支援**：單一 Issue 可由多人共同處理\n- 🎯 **靈活專案配置**：支援標籤篩選或全開放 Issue 擷取\n- 📅 **時間範圍控制**：可設定起始日期進行過濾\n\n## 系統架構\n\n```\nGitLab API ──► 數據處理器 ──► Google Sheet ──► 甘特圖 ──► 樞紐分析表報表\n    ↓              ↓              ↓           ↓           ↓\n  Issue 擷取    標籤篩選      時間軸生成   進度追蹤    工作分析\n```\n\n### 模組結構\n\n| 模組 | 功能說明 |\n|------|----------|\n| `main.py` | 主程序入口，整合各模組功能 |\n| `argument_parser.py` | 命令行參數解析，支援報表與年份參數 |\n| `config_handler.py` | 配置管理，支援欄位定義與用戶角色 |\n| `gitlab_api_handler.py` | GitLab API 互動，含重試機制 |\n| `data_processor.py` | 數據處理與篩選邏輯 |\n| `google_sheet_api_handler.py` | Google Sheet API 操作 |\n| `worksheet_manager.py` | 甘特圖工作表管理 |\n| `report_generator.py` | 樞紐分析表報表生成 |\n| `utils.py` | 日期處理與工具函數 |\n| `logger.py` | 系統日誌管理 |\n\n## 安裝與設定\n\n### 1. 系統需求\n\n- Python 3.6 或更高版本\n- 網路連線至 GitLab 和 Google API\n- GitLab API 存取權限\n- Google API 服務帳號憑證\n\n### 2. 安裝依賴套件\n\n```bash\npip install -r requirements.txt\n```\n\n**主要依賴套件：**\n```txt\ngoogle-api-python-client==2.79.0\ngoogle-auth==2.16.0\ngoogle-auth-httplib2==0.1.0\ngoogle-auth-oauthlib==1.0.0\npython-gitlab==3.13.0\npyyaml==6.0\nsystemd-python==234\nrequests==2.28.2\n```\n\n### 3. Google API 設定\n\n1. 前往 [Google Cloud Console](https://console.cloud.google.com/)\n2. 創建專案並啟用 Google Sheets API\n3. 創建服務帳號並下載 JSON 憑證檔案\n4. 將 Google Sheet 共享給服務帳號的電子郵件地址\n5. 更新 `config.yaml` 中的憑證路徑\n\n### 4. GitLab API 設定\n\n1. 登入 GitLab 並前往個人設定\n2. 創建具有 `api` 權限的個人存取權杖\n3. 更新 `config.yaml` 中的權杖資訊\n\n## 配置檔案說明\n\n### 基本配置結構\n\n```yaml\n# Google Sheet 配置\ngoogle_sheet:\n  credentials_path: \"/path/to/credentials.json\"\n  spreadsheet_id: \"your_spreadsheet_id\"\n\n  # 報表設定\n  report_settings:\n    workday_highlight_method: \"outlier\"  # 高亮方法：outlier (離群值) 或 top_n (前 N 個最大值)\n    workday_highlight_outlier_multiplier: 1.5  # 離群值倍數（使用 Q3 + multiplier * IQR），預設 1.5\n\n  # 工作表欄位定義\n  worksheet_columns:\n    gitlab_link: 0        # A 欄 - GitLab 連結\n    issue_title: 1        # B 欄 - Issue 標題\n    owner: 2              # C 欄 - 負責人\n    type: 3               # D 欄 - 工作類型\n    subtype: 4            # E 欄 - 第二階工作類型\n    closed: 5             # F 欄 - 是否關閉\n    note: 6               # G 欄 - 備註\n    timeline_start: 7     # H 欄 - 時間軸開始位置\n\n# GitLab 配置\ngitlab:\n  base_url: \"https://your-gitlab.com\"\n  token: \"your_api_token\"\n\n  # 專案設定（支援混合模式）\n  project_id_list:\n    - 123  # 只抓取根據全域標籤篩選的 issue\n    # 以下段落是設定所有 issue 都抓取\n    - project_id: 456\n      name: \"專案名稱\"\n      fetch_all_open_issues: true  # 擷取所有開放 issue\n\n  # 全域標籤列表\n  label_list:\n    - \"A::B\"\n    - \"C::D\"\n    - \"E::F\"\n\n  # 使用者與角色管理\n  user_list:\n    - \"user1\"\n    - \"user2\"\n    - \"manager1\"\n\n  user_roles:\n    managers:  # 主管角色（排除在個人報表外）\n      - \"manager1\"\n\n  # 工作分類定義\n  # 若有新增項目，只有觸發 `新建工作表` 的行為才會套用新的項目，\n  # 舊有的需要在 Google Sheet 的 資料 \u003e 資料驗證 進行修改\n  type_list:\n    - \"A\"\n    - \"B\"\n    - \"C\"\n    - \"其他\"\n\n  subtype_list:\n    - \"客服進單\"\n    - \"日常維運\"\n    - \"硬體報修\"\n    - \"專案支援\"\n\n# 日誌配置\nlog_config:\n  level: \"INFO\"\n  tag: \"gitlab-gantt-sync\"\n  console_output: false\n```\n\n## 使用方法\n\n### 基本操作\n\n```bash\n# 僅更新甘特圖（不生成報表）\npython3 main.py\n\n# 僅生成樞紐分析表報表（跳過 GitLab Issue 同步）\npython3 main.py -r\npython3 main.py --report\n\n# 指定年份生成報表\npython3 main.py -r -y 2025\npython3 main.py --report --year 2025\n\n# 指定年份更新甘特圖\npython3 main.py -y 2024\n\n# 生成年度工作樞紐分析表\npython3 main.py -a\npython3 main.py --annual-work\n\n# 指定年份生成年度工作樞紐分析表\npython3 main.py -a -y 2025\n```\n\n### 命令行參數\n\n| 參數 | 說明 |\n|------|------|\n| `-r`, `--report` | 生成雙月報表。若指定此參數，則僅生成報表，跳過 GitLab Issue 同步。 |\n| `-y`, `--year` | 指定報表年度。若不指定則使用當年。 |\n| `-a`, `--annual-work` | 生成年度工作樞紐分析表。從報表工作表的 K-N 欄讀取數據，生成按 SubType/Type 分類的樞紐分析表。 |\n\n### 自動化部署\n\n#### Crontab 設定範例\n\n```bash\n# 每日凌晨更新甘特圖\n0 0 * * * /usr/bin/python3 /path/to/main.py\n\n# 每月1日生成報表\n0 0 1 * * /usr/bin/python3 /path/to/main.py --report\n\n# 每週一檢查並同步\n0 8 * * 1 /usr/bin/python3 /path/to/main.py\n```\n\n#### systemd 服務設定\n\n```ini\n[Unit]\nDescription=GitLab Issue Gantt Sync\nAfter=network.target\n\n[Service]\nType=oneshot\nUser=ubuntu\nExecStart=/usr/bin/python3 /path/to/main.py\nWorkingDirectory=/path/to/project\n```\n\n## 工作流程說明\n\n### 1. 自動化部分\n\n- ✅ 從 GitLab 擷取 Issue 資訊並填入 A、B 欄\n- ✅ 自動生成完整年度甘特圖時間軸\n- ✅ 創建 Owner、Type、SubType 下拉選單\n- ✅ 創建 Closed 欄位的核取方塊\n- ✅ 設定週末背景色與欄位格式\n\n### 2. 手動操作部分\n\n- 📝 **C 欄 (Owner)**：選擇負責人\n- 📝 **D 欄 (Type)**：選擇工作類型（VCS、VKS、VDS等）\n- 📝 **E 欄 (SubType)**：選擇子類型（客服進單、日常維運等）\n- 📝 **F 欄 (Closed)**：勾選是否已關閉\n- 📝 **G 欄 (Note)**：填寫備註\n- 📝 **時間軸區域**：填入處理 Issue 的人員名稱（支援多人，以逗號分隔）\n\n### 3. 報表產出\n\n- 📊 系統自動根據甘特圖數據生成雙月樞紐分析表\n- 📈 顯示各人員在不同工作類型的時間分配\n- 📉 計算各類型工作的佔比及與前期的變化趨勢\n- 👤 為每個一般使用者（非主管）生成獨立報表頁籤\n\n## 報表功能詳解\n\n### 樞紐分析表結構\n\n| 欄位 | 說明 |\n|------|------|\n| Type | 工作類型（VCS、VKS等） |\n| SubType | 第二階分類（客服進單、日常維運等） |\n| Issue | 具體 Issue 標題 |\n| Workday | 工作天數 |\n| Workday 佔比 | 該 Issue 在總工作天數中的比例 |\n| Workday @ SubType 佔比 | SubType 在總工作天數中的比例 |\n| SubType 與前次雙月差異 | 與前一個雙月期間的變化 |\n| Workday @ Type 佔比 | Type 在總工作天數中的比例 |\n| Type 與前次雙月差異 | 與前一個雙月期間的變化 |\n\n### 報表特色\n\n- 🎯 **Issue 級別統計**：精確到每個 Issue 的工作天數\n- 📊 **多層次分析**：Type → SubType → Issue 的階層結構\n- 📈 **趨勢比較**：與前一個雙月期間的百分比變化\n- 👥 **個人化報表**：每位成員獨立的工作統計頁籤\n- 🔢 **自動計算**：合併儲存格與百分比格式自動處理\n\n### Workday 高亮標示條件\n\n報表中會自動將花費時間較多的 Issue 以黃色背景標示（Workday 和 Workday 佔比欄位）。\n\n#### 離群值檢測演算法（IQR 方法）\n\n系統使用四分位距（Interquartile Range, IQR）方法檢測離群值：\n\n1. **計算四分位數**：\n   - Q1（第 25 百分位數）\n   - Q3（第 75 百分位數）\n   - IQR = Q3 - Q1\n\n2. **計算閾值**：\n   ```\n   threshold = Q3 + multiplier × IQR\n   ```\n   - 預設 `multiplier = 1.5`（可在 `config.yaml` 中調整）\n\n3. **標示條件**：\n   - 當 `Workday \u003e threshold` 時，該列的 Workday 和 Workday 佔比欄位會以黃色背景標示\n   - 若數據量少於 4 筆，則僅標示最大值\n\n4. **適用範圍**：\n   - 雙月報表：各期間獨立計算閾值\n   - 年度總覽：使用全年數據計算閾值\n\n#### 配置選項\n\n```yaml\ngoogle_sheet:\n  report_settings:\n    workday_highlight_method: \"outlier\"  # 高亮方法\n    workday_highlight_outlier_multiplier: 1.5  # IQR 倍數\n```\n\n## 故障排除\n\n### 常見問題\n\n#### 1. Google API 認證錯誤\n```bash\n# 檢查憑證檔案路徑和權限\nls -la /path/to/credentials.json\n```\n\n**解決方案：**\n- 確認憑證檔案存在且可讀取\n- 檢查服務帳號是否有 Google Sheet 存取權限\n- 驗證 spreadsheet_id 是否正確\n\n#### 2. GitLab API 連線失敗\n```bash\n# 測試 API 連線\ncurl -H \"PRIVATE-TOKEN: your_token\" \"https://your-gitlab.com/api/v4/projects\"\n```\n\n**解決方案：**\n- 檢查 GitLab URL 和 token 設定\n- 確認 token 具有 `api` 權限\n- 檢查網路連線狀態\n\n#### 3. 工作表結構錯誤\n**症狀：** 時間軸生成失敗或數據同步異常\n\n**解決方案：**\n- 檢查 `config.yaml` 中的欄位定義\n- 確認工作表標頭與預期一致\n- 重新生成工作表或手動調整結構\n\n### 日誌查看\n\n```bash\n# 查看系統日誌\njournalctl -t gitlab-gantt-sync\n\n# 查看最近的錯誤\njournalctl -t gitlab-gantt-sync -p err --since \"1 hour ago\"\n\n# 即時監控日誌\njournalctl -t gitlab-gantt-sync -f\n```\n\n### 除錯模式\n\n```yaml\n# 臨時啟用除錯模式\nlog_config:\n  level: \"DEBUG\"\n  console_output: true\n```\n\n## 效能調優\n\n### API 配額管理\n\n- **Google Sheets API**：預設每批次 3 個請求，間隔 0.5 秒\n- **GitLab API**：重試機制 3 次，間隔 5 分鐘\n- **報表生成**：用戶間延遲 15 秒，避免配額超限\n\n### 快取機制\n\n- 工作表數據快取，避免重複 API 調用\n- 時間軸解析結果快取，提升報表生成效率\n\n## 擴展功能\n\n### 新增工作類型\n\n1. 編輯 `config.yaml` 中的 `type_list` 和 `subtype_list`\n2. 重新執行程式，下拉選單將自動更新\n\n### 自訂欄位配置\n\n1. 修改 `config.yaml` 中的 `worksheet_columns`\n2. 調整 `expected_headers` 對應的標頭名稱\n3. 系統將自動適配新的欄位結構\n\n### 新增專案監控\n\n```yaml\ngitlab:\n  project_id_list:\n    - project_id: 新專案ID\n      name: \"專案名稱\"\n      fetch_all_open_issues: true  # 或使用標籤篩選\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimhuang1204%2Fissue-gantt-sync","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimhuang1204%2Fissue-gantt-sync","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimhuang1204%2Fissue-gantt-sync/lists"}