探討-如何讓團(tuán)隊(duì)了解產(chǎn)品進(jìn)度

對(duì)于一個(gè)人數(shù)30-50的創(chuàng)業(yè)團(tuán)隊(duì)來說,如何讓每個(gè)成員及時(shí)了解產(chǎn)品的變化是一個(gè)有意思的話題

為什么讓產(chǎn)品信息共享?

因?yàn)椋瑘F(tuán)隊(duì)不同的 team 的工作側(cè)重點(diǎn)各有不同:

  1. Support Team 關(guān)注用戶使用產(chǎn)品時(shí)出現(xiàn)的問題,及時(shí)掌握產(chǎn)品變化,可以讓 Support Team 的工作有預(yù)先準(zhǔn)備,給用戶提供最新指導(dǎo),工作效率更高。
  2. Growth Team 關(guān)注產(chǎn)品的價(jià)值,舊功能的優(yōu)化和新功能的上線都會(huì)影響他們的決策,例如 A/B Test,QA 等。
  3. Develop Team 關(guān)注產(chǎn)品的功能實(shí)現(xiàn),別人代碼的更新可能會(huì)影響自己的開發(fā)。

“變化”的分類:

  1. 大變化:可以理解為milestone (里程碑),比如大功能的上線。
    1. 這種大的變化適合專門的文檔去記錄,比如產(chǎn)品更新Blog:簡單明了的文字、截圖、視頻教程等。
  2. 小變化:
    1. 用戶看得見的變化:小的UI優(yōu)化,Bug修復(fù)。
    2. 用戶體驗(yàn)的變化:性能的優(yōu)化(更加流暢),交互的變化(更加合理)。

解決思路

第一個(gè)問題,如何搜集變化?

  1. 方案一:成員每日寫工作總結(jié)。
    1. 根據(jù)工作內(nèi)容抽離出“變化”。
    2. 有個(gè)成員專門去維護(hù)一個(gè)或一系列文檔。
    3. 優(yōu)點(diǎn):系統(tǒng)性強(qiáng)。
    4. 缺點(diǎn):人力成本高,適合有一定規(guī)模的團(tuán)隊(duì)。
  2. 方案二:可以維護(hù)一個(gè) wiki。
    1. 每個(gè)成員主動(dòng)將“變化”寫入文檔中去。
    2. 優(yōu)點(diǎn):調(diào)動(dòng)成員的積極性。
    3. 缺點(diǎn):
      1. 需要一些工具,如文檔協(xié)作,存儲(chǔ)與檢索。
      2. 需要一些規(guī)范和 review。
  3. 方案三:利用第三方工具 (github) 自動(dòng)搜集。
    1. 檢索 Pull Request 中詳細(xì)描述這次PR的內(nèi)容,搜集起來。
    2. 優(yōu)點(diǎn):節(jié)省人力,有利于PR規(guī)范化。
    3. 缺點(diǎn):需要相關(guān)開發(fā)工作。

我們 Strikingly 崇尚敏捷,高效和自動(dòng)化。采用了方案三。Develop Team 使用 Pull Request 模板,每天將特殊的 Pull Request 搜集起來。

第二個(gè)問題,如何通知每個(gè)成員?

  1. 發(fā)消息:“去看文檔的更新”
    1. 優(yōu)點(diǎn):可以融入我們的日常交流中去。
    2. 缺點(diǎn):消息流很容易丟失在其他討論中
  2. 發(fā)郵件:將產(chǎn)品的“變化”寫進(jìn)郵件里面。
    1. 優(yōu)點(diǎn):比較正式,可自定義HTML,樣式可控制,便于給歸檔。
    2. 缺點(diǎn):需要相關(guān)開發(fā)工作。

我們決定采用郵件的方式,每天發(fā)送一個(gè)以郵件的形式通知團(tuán)隊(duì)的每個(gè)人。

結(jié)合起來后大致分成7個(gè)步驟:

  1. 設(shè)置Github
  2. 約定PR模板
  3. 記錄部署時(shí)間
  4. 處理 github webhook
  5. 數(shù)據(jù)存儲(chǔ)到 Redis
  6. 準(zhǔn)備郵件
  7. 循環(huán)發(fā)郵件

開發(fā)配置相關(guān):

  1. Rails 后端
  2. Redis 臨時(shí)存儲(chǔ)
  3. github 的 webhook 服務(wù)
  4. 用到的一些 gem:
    1. git_api: 訪問 github API
    2. maruku: 將 Markdown 轉(zhuǎn)換為 HTML
    3. sidekiq/sidetiq: 后臺(tái)循環(huán)發(fā)送郵件

Step 1: 設(shè)置 Github

  1. 項(xiàng)目的 settings 中設(shè)置 webhook
    1. 設(shè)置 Payload URL
    2. 設(shè)置 events 類型:勾選 Pull Request
  2. 添加 Personal access token
  3. 使用 gem github_api, 添加配置文件

Step 2: 約定 PR 模板

示例 PR 模板:

pr_template.png

模板的重要性:

  1. 規(guī)范 Develop Team 的開發(fā)流程。
  2. 如果不使用模板,我們開發(fā)的這個(gè)工具,沒有任何卵用O__O"…

Step 3: 記錄部署時(shí)間

由于有些PR雖然被merge了,但并不一定被部署了,所以我們需要將最近一次部署的時(shí)間記錄下來。

class DeployLogger
  DEPLOY_KEY = 'AWESOME_REPO_LAST_DEPLOY_KEY'

  # 根據(jù)實(shí)際情況使用默認(rèn)時(shí)間
  def self.deploy_at
    $redis.get(DEPLOY_KEY) || '2015-08-10T02:27:38Z'
  end

  def self.deploy_at= time
    $redis.set DEPLOY_KEY, time
    $redis.expire DEPLOY_KEY, 60.days
  end
end

Step 4: 處理 github webhook

  1. 獲取 PR 的 Number
  2. 因?yàn)槲覀儾⒉荒芟嘈?webhook,所以我們應(yīng)該基于 webhook 的信息主動(dòng)通過 github API 獲取數(shù)據(jù)。
  3. 篩選PR: merged 到指定分支(develop) 且含有 - [x] contains user facing changes
  4. 整合信息,提取出 PR 的Number,title,body,獲取 PR 提交username等。

Step 5: 存儲(chǔ)到 Redis

class PrDescription
  LAST_SEND_EMAIL_KEY = 'LAST_SEND_EMAIL_KEY'

  # 使用 redis ordered set
  # merged_at 時(shí)間秒數(shù)作為 score
  def self.create columns = {}
    key_word = columns[:key_word]
    merged_at = columns[:merged_at]
    content = columns[:content]
    $redis.zadd key_word, Time.parse(merged_at).to_i, content
    $redis.expire key_word, 2.days
  end

  def self.count_of key_word
    $redis.zcount key_word, '-inf', '+inf'
  end

 # 根據(jù)情況做適當(dāng)調(diào)整
  def self.last_send_email_at
    $redis.get(LAST_SEND_EMAIL_KEY) || '2015-08-10T02:27:38Z'
  end

 # 根據(jù)情況做適當(dāng)調(diào)整
  def self.last_send_email_at= time
    $redis.set LAST_SEND_EMAIL_KEY, time
    $redis.expire LAST_SEND_EMAIL_KEY, 5.days
  end

  # 獲取當(dāng)前部署好的PR
  # 范圍:最近的一次發(fā)郵件的時(shí)間到最近的一次部署時(shí)間
  def self.descriptions_need_to_send_for key_word
    from_time_score = Time.parse(self.last_send_email_at).to_i + 0.01
    to_time_score = Time.parse(DeployLogger.deploy_at).to_i
    $redis.zrangebyscore key_word, from_time_score, to_time_score
  end
end

Step 6: 準(zhǔn)備郵件

# 在每個(gè) PrDescription 之間要用"\n"隔開,注意是雙引號(hào),需要轉(zhuǎn)義,不能加空格,會(huì)影響 Markdown 的轉(zhuǎn)化
markdown_string = PrDescription.descriptions_need_to_send_for(USER_FACING_CHANGES_KEY).join("\n")

if markdown_string.present?
  # 使用gem maruku 將Markdown
  # 有些小問題:
  #   1. 需要將 " 轉(zhuǎn)換成 '
  #   2. 去除 '\n'
  @content = Maruku.new(markdown_string).to_html.gsub(/\"/,"'").gsub(/\n/, '').html_safe
  mail subject: "User Facing Changes #{Date.today}", from: PRODUCT_EMAIL, to: TEAM_EMAIL
  # 設(shè)置最后一次發(fā)郵件的時(shí)間
  PrDescription.last_send_email_at = DeployLogger.deploy_at
end

Step 7: 循環(huán)發(fā)郵件

# 用到 gem: sidekiq 和 sidetiq
class SendToSupportTeamChangesEmail
  include Sidekiq::Worker
  include Sidetiq::Schedulable

  sidekiq_options :queue => :default, :backtrace => true, :retry => 2

  # everyday 8:30 AM 
  # 請(qǐng)注意時(shí)區(qū),可能需要轉(zhuǎn)換
  recurrence { daily.hour_of_day(8).minute_of_hour(30) }

  def perform
    # 負(fù)責(zé)發(fā)送內(nèi)部郵件的類
    InternalMailer.user_facing_change_email.deliver
  end
end

最后,如果今天有PR merged 到 develop 分支并且還被部署到 production 環(huán)境,我們明天一早會(huì)受到一封郵件:

這方面的探索還在繼續(xù),思路和代碼還有可多地方可以提升,請(qǐng)各位多多指教。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,711評(píng)論 19 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,355評(píng)論 25 708
  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一種新的協(xié)議。它實(shí)...
    香橙柚子閱讀 24,832評(píng)論 8 183
  • 上一講說端起,放下。本講就說說在易學(xué)范圍內(nèi),我所沒有介紹的內(nèi)容,我之所以不介紹,因?yàn)槲覜]學(xué),也不會(huì)。 一、“知其所...
    童年的流星閱讀 773評(píng)論 1 10
  • 01 前段時(shí)間在華南理工開展工作坊時(shí),偉寧同學(xué)充滿自豪地說:每學(xué)期讀8本(課外)書。 我喜歡偉寧同學(xué),和他也很熟,...
    韓惟庸韓大爺閱讀 227評(píng)論 0 2

友情鏈接更多精彩內(nèi)容