談 Git 的開發流程

很高興受邀參加『FED Party 10』GIT的develop與master 論壇成為與談人。其中「協同開發時,master 與 dev branch 如何規劃?」這個問題是我主要講述的部份,分享了團隊用 Git 的開發流程經驗。

2010 年的 GitFlow 是一個很好的開始,它提供了一個很清楚的開發流程,幾乎可說是目前用 Git 的「標準開發流程」。不過流程的目的是為了幫助軟體開發和釋出,而不同團隊有著不同的需求,也就不可能有 “One size fits all ” 的解法。

撇開 Gitflow 比較囉唆(或者你要說它比較嚴謹?)的流程,我認為最大的問題(或天性)是它比較適合搭配 Iteration-based 流程(一批功能完成才進行釋出、週期性佈署),而不是 Kanban 流程 (一個功能完成就進行釋出、每天多次佈署)。怎麼說呢?

假設團隊這次 iteration 同時在開發 A,B,C 三個 features。在 GitFlow 之中,我們通常不會一個 feature 寫好就開 release branch,而是會等到 A,B,C 都完成了,在一起開 release branch 跑 CI 上 staging server 一起測試。這時候問題就來了,如果 feature A 測試有問題,即使 B,C 沒問題,整個 release branch 也會卡住無法釋出。這一卡可能又拖了好幾天…

理想的 Kanban 流程會希望一個 feature 完成就能推上 production 釋出。這時候 release branch 的設計就顯得礙手礙腳了。那要怎麼達到一個 feature 可以單獨釋出呢? 首先你會需要多重 CI 和 staging servers 的環境。每新開一個 feature branch 就會有各自對應的 CI 和 staging server 可以進行測試,這樣只要該 feature branch 測試完成,就代表可以合併回主幹進行釋出動作。話說回來,這其實就是 GitHub Flow 流程。

實務上,你也可以預先開好數台 staging 機器,然後讓開發者可以佈署 feature branch 上去進行QA測試。這樣就不需要辦到隨時動態開 staging 機器的技術能力。

如果 staging 機器真的有限制只能開一台,另一個變形作法是有一個專門的 staging branch,需要上 staging 機器進行測試的 feature branch 就合併進 staging branch 進行佈署。但是注意到這個 staging branch 並不會合併回主幹,它是永遠平行的。也就是說 staging branch 上可能包含 A,B,C feature branchs,當 feature B 在 staging 上測試完成,就合併 feature B branch 回主幹,而不是 staging branch。這算是一個 workaround 的作法,我們公司就有團隊就採用這個作法,也非常實用。

總之,無論採用何種流程,我的重點在於必須一併考慮如何搭配 CI、Code Review、手動 QA 測試等等整套軟體釋出流程,才是通盤的考量。

參考資料

講個秘訣:加快 git pull 和 git push 速度

SSH 有個功能是可以沿用已經存在的 host 連線,如果再連一次就會比較快。首先編輯 ~/.ssh/config 加上:


ControlMaster auto
ControlPath /tmp/ssh_mux_%h_%p_%r

接著讓我們一直掛著 GitHub 的 SSH 連線……


ssh -N git@github.com

讓我們實驗看看效果如何:

使用前:


> time git pull

real	0m3.117s
user	0m0.055s
sys	0m0.045s

使用後:


> time git pull

real	0m0.765s
user	0m0.037s
sys	0m0.042s

嗯,效果非常好。

出處:GitHub hack: speed up git push and git pull

Systems Operations on AWS 課

這禮拜去參加 Systems Operations on AWS 課程,上課的範圍其實跟上次的 Architecting on AWS 很接近,重點跟細節程度有些差異,操作 Labs 更多有九個,而且不少是用 CLI 操作而非 Management Console。上課也比較注重操作細節,連投影片字也比較多… XD

第一天教 VPC 跟 EC2,Lab1 是操作設定 Public Subsnet+Private Subnet+IGW+NAT,不像上次的課用 Wizard 設定,這次需要一個一個設定進行操作。 Lab2 練習用 AWS command line (CLI) 開 ec2 機器。

第二天教 EBS, Tagging, Monitoring, Backup 等等。Lab3 用 CLI 操作 EBS Snapshot、EBS Prewarn、合併兩個 EBS 成更大的 Logical Volumn。Lab4 用 CLI 操作 Tagging。Lab5 設定 Custom Metric 到 CloudWatch,並設定 Custom Alerm (這可以用來搭配 Auto scaling)、練習整合 Auto scaling 和 3-party Monitoring 工具(當新增或移除機器時,會通知 Monitoring server)。Lab6 則是資料庫的 Backup&Restore,使用 EBS Snapshot 和 RDS 不同方式練習。這裡它特別強調 Consistent snapshots 的概念,需要 pause write 和 flush to disk 並鎖住 DB 才作 Snapshot。Lab 7 是一個用 CLI 抓 RDS 重設密碼事件的小練習。

這一天最大的收穫應該是了解 CloudWatch 可以做 Custom Metric,以來它可以用來搭配 Auto Scaling 使用,以及如何整合 3-party monitoring 工具。

第三天教 Log 管理(因應 Auto Scaling,所以 Logs 有集中管理的需求)、Auto Scaling 跟 Cost 管理。Lab 8 練習設定 Logrotate 把 logs 傳到 s3,以及在 Auto Scaling 的情況下,記得關機前傳 log。Lab 9 練習建立一個 Auto Scaling 環境,也是一樣有一個做好的 PHP 會模擬操 CPU,然後就 scaling 自動開機器。這個練習跟上次上課的很像。最後還有一個不是 Lab 的練習是分析一個 Cost 成本 Excel 表。

對了,我會建議上課記得帶個平板 iPad,他的講義有 App 可以離線閱讀。這樣 Lab 操作時就可以邊看邊操作。

Architecting on AWS 課

這禮拜去上了三天的 Architecting on AWSTraining 課。查了一下這課在美國要收 USD $1,800,不知道為什麼台灣這麼好是免費的,佛心。

講師是個印度人,英文口音一開始有點不太習慣,不過反正跟著投影片教材走,理解上不會有太大的困難。教材是要來上課現場才會開放讓你下載的,算是這課的精華所在吧。教材投影片包含了詳細的註解補充很不錯,Lab 教材則有一步一步的操作說明,照著作就可以完成練習。

第一天: 上架構原則跟安全知識,Lab 1 練習開 VPC 網路

第二天: 介紹 IAM,Lab 2 練習設定 IAM。接著介紹 Route 53, ELB, CloudFront, CloudWatch, Elastic Beantalk 跟 CloudFormation。介紹 Auto scaling 的觀念跟 Pattern、如何 bootstrapping ec2 instances、Storage scaling (EBS,S3…etc) 的策略跟使用情境。最後是 Lab 3 設定一個 Auto scaling 架構出來,它給了一個簡單的 web app 可以操CPU,然後自動開 EC2 instances 擴充上去。挺有意思。下課前分組討論一個模擬架構是跨 regions 的文件分享系統。

第三天: 介紹 Application services: SQS, SNS, SWF, SES, CloudSearch 等等、Cost 概念以及 HA(high availability) 跟 Disaster Recovery(DR) 概念跟策略,最後教如何說服老闆改用 Cloud 架構、如何寫搬家計畫等等。Lab 4 則是利用 SQS 跟 Auto scaling 設定一個 Batch Processing Cluster,它給了一個簡單的圖片處理 script 當作 worker instances,然後當 SQS 等待的訊息過多時,會自動開 ec2 instance 擴充上去,處理完的圖片丟上 S3,也是一個很有趣的練習。

內容雖然免不了有基本 AWS 功能介紹,不過有教一些架構策略跟 Lab 練習算是不錯的收穫。VPC 跟 auto scaling 我之前都是知道但沒實際操作過,這次跟著教材練習很快就完成了 :)

我還報名了兩週後的 Systems Operations on AWS 課,到時再來比較看看。

BTW,午餐是 Buffet 自助餐還不錯。

RubyConf Taiwan 2014 售票開始

今年的 RubyConf Taiwan 日期是 4/25-26,地點在陽明大學,目前已經開放報名啦!!

本屆 RubyConf Taiwan 的邀請講者有:Rails Girls 社群創辦人 Linda Liukas 和 Terence Lee,她們將一同上台分享Rails Girls社群創辦經驗;Ruby 之父松本行弘先生與 Ruby 核心開發者笹田耕一先生是第二次在 RubyConf Taiwan 進行演講,展現他們對 Ruby 社群在台灣發展盛況的贊許與支持;還有 JRuby 的主要開發者 Charles Nutter;另外,以良葛格之名廣為人知的 Java 及 Python 語言的教育專家林信良先生也將發表主題演講;更有來自國內外的諸多程式好手分享心得與發現。本屆會議的內容精采可期,不容錯過。

摘錄自新聞稿

如何在本地端取出和送出 Github 的 Pull Requests

最近意識到 Github 上的 pull requests 其實也是 branches 參照,所以你也可以根據 pull request 編號在本地端直接取出。對於常用 pull request 功能來作 code review 的團隊來說,是蠻方便的小技巧。

首先編輯專案下的 .git/config,加上 fetch = +refs/pull/*/head:refs/remotes/origin/pr/* 這一行,例如:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = git@github.com:ihower/sandbox.git
    fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

接著打 git fetch origin 就會抓下來這些 remote branches:

From github.com:eduvo/keybridge
 * [new ref]         refs/pull/1/head -> origin/pr/1
 * [new ref]         refs/pull/2/head -> origin/pr/2
 * [new ref]         refs/pull/3/head -> origin/pr/3

接著用 checkout 取出,例如 git checkout pr/3 即可。

喜歡的話,也可以設成 git 全域設定,直接套用所有專案:

git config --global --add remote.origin.fetch "+refs/pull/*/head:refs/remotes/origin/pr/*"

參考資料: Checkout Pull Requests Locally

本地端送 Pull request

舉一反三,那要怎麼在本地端送 Github 的 Pull Request? 參考 HSATAC 的這篇:用 Commandline 發 Github Pull Request

首先安裝 github 的 hub 工具:

brew install hub # 或
gem install hub

編輯 ~/.bash_profile

# https://gist.github.com/hSATAC/5591270#file-gistfile1-sh
# Usage: pr (pull request current branch into develop)
# Usage 2: pr stable (pull request current branch into stable)
# Notice: replace "team" with your github team account.
 
function pr() {
    base=$1;
    if [ "$1" == "" ]; then
        base="develop"
    fi
    hub pull-request -b team:"$base" -h team:`git rev-parse --abbrev-ref HEAD`;
}