這篇原本是 Stephen(@bauhouse) 寫給 Symphony Factory ensemble 的開發流程,由於該建構需要讓社群能夠持續參與維護,如何透過 GitHub 同步開發的進度,包含資料庫的異動,就成了重要的議題。因為 Symphony CMS 雖然將核心與客製的程序有基本的區分,但安裝外掛、新增資料表、新增頁面等流程都會異動到資料庫,就造成 Symphony CMS 在一般的 DTAP 流程不太順暢。
正規的 DTAP 開發環境:
- Development:指每位開發者本地端的開發環境
- Testing:開發流程中,開發者彼此溝通、檢查的測試環境
- Acceptance:通常所謂的 Stage,讓非程式開發者檢查、確認是否滿足需求的環境
- Production:正式上線的環境
嘗試以此文為基礎,確認一個 Symphony CMS 專案的最適開發流程。
原文參考資料:
了解如何使用 Git 是必要的:
- Getting Git for Symphony Development by Jonas Downey
- Using git and Symphony CMS by Rowan Lewis
- On Git Submodules by Nils Werner
- A Symphony Workflow by John Porter
在 Symphony 討論區也有一些有趣的討論串值得一看:
- PHP 5.2 or above(目前推薦使用 PHP 5.3)
- PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
- MySQL 5.0 or above
- An Apache or Litespeed webserver
- Apache's mod_rewrite module or equivalent
什麼是 Symphony Ensemble? 官網上的基本解說 。
Ensembles 把整個專案建構,包含資料庫以及工作目錄中所有的客製資料,打包成一個可用於安裝的套件。對一般人來說,透過任何方式將 ensemble 解壓、擺放到主機的網站目錄下,設置好一個空的資料庫(記下相關資訊),就可以透過網頁安裝界面,幾分鐘之內安裝完成。
必須在本地端設置好必要的開發環境。
使用 Mac OS X 內建的 Apache 網站伺服器,需要建立兩個虛擬站點(virtual hosts)。將 *.local
模擬成正式站台,而 *.dev
就是本地開發環境,用來除錯、添加新功能等。
編輯 /etc/hosts
檔案:
### Projects
127.0.0.1 getsymphony.dev
127.0.0.1 getsymphony.local
伺服器設定檔 /etc/apache2/httpd.conf
會有這麼一行,用來載入使用者的額外設定(通常是 USERNAME.conf
),就不會動到系統內建設定:
Include /private/etc/apache2/other/*.conf
使用者設定檔 /etc/apache2/users/USERNAME.conf
會有下面內容:
NameVirtualHost *:80
NameVirtualHost 127.0.0.1
<Directory "/Users/USERNAME/Sites">
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
DirectoryIndex index.php index.html index.htm
</Directory>
<VirtualHost 127.0.0.1>
ServerName getsymphony.dev
DocumentRoot /Users/USERNAME/Sites/projects/getsymphony/dev/public
</VirtualHost>
<VirtualHost 127.0.0.1>
ServerName getsymphony.local
DocumentRoot /Users/USERNAME/Sites/projects/getsymphony/local/public
</VirtualHost>
自行指定本地的網址對應、檔案擺放位置,儲存之後,從終端機重啟 Apache:
sudo apachectl restart
接著示範一下,如何使用 XSLT 測試開發環境。
這只是個笨笨的小示範,展示了在 Unix-based 系統(包含 Mac 與 Linux)上,如何使用預設就安裝好的 XSLT 編譯程序。
如果還沒有設置完成,先建立網站的根目錄,我們需要從瀏覽器檢查最後的結果。Mac OS X 已經不再預設建立 Sites
目錄,所以設置好自己的對應,打開終端機,建立下面兩個檔案:
建立一個簡單的 XML 檔案,取名為 hello.xml
:
<?xml version="1.0" encoding="utf-8"?>
<data>
<salutation>Hello, World!</salutation>
</data>
建立名為 hello.xsl
的 XSLT 檔案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
omit-xml-declaration="yes"
encoding="UTF-8"
indent="yes" />
<xsl:template match="/">
<xsl:param name="salutation" select="data/salutation" />
<html>
<head>
<title><xsl:value-of select="$salutation" /></title>
</head>
<body>
<h1><xsl:value-of select="$salutation" /></h1>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
接著打開終端機,進行下列操作:
xsltproc -v -o ~/Sites/projects/getsymphony/dev/public/index.html hello.xsl hello.xml
xsltproc -v -o ~/Sites/projects/getsymphony/local/public/index.html hello.xsl hello.xml
只要有安裝 xsltproc (Mac 與 Linux 應該預設就有),上面程序會建立兩個目標檔案(包含目錄):
~/Sites/projects/getsymphony/dev/public/index.html
~/Sites/projects/getsymphony/local/public/index.html
接著只要重啟 Apache 伺服器,瀏覽下面兩個虛擬站點:
首頁應該會對你說 "Hello, World!",就像下面這樣:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Hello, World!</title>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
頁面都是機器可判讀的 XHTML 格式了(注意 !DOCTYPE
)
一開始先從開發站點 getsymphony.dev
開始,畢竟我們還沒有一個已經正式上線的 getsymphony.local
環境:
切換到 getsympphony.dev
對應的網站目錄 public
:
cd ~/Sites/projects/getsymphony/dev/public
為了複製 git 倉儲到 public 目錄,我們得先將目錄清空(git 無法複製到一個已有檔案的目錄),因此刪除掉剛剛用來建立目錄的 index.html
檔案。
rm index.html
確認目錄是否真的是空的(檢查有沒有隱藏檔案):
ls -al
確認系統上已安裝 Git:
git --version
Mac OS X 若是安裝了 Xcode,就會安裝好了 Git(但版本稍舊,建議用 homebrew 安裝新版):
git version 1.7.12.4 (Apple Git-37)
下面的指令,可以從專案目錄下複製遠端倉儲(指令末端的 .
),同時也使用遞迴指令 --recursive
,確保核心外掛模組都一併複製完成。
git clone --recursive git://github.com/symphonycms/symphony-2.git .
因為上面是使用 git clone Symphony-2 倉儲,因此 master 分支就是目前的版本。而我們需要四個分支:
- master:production site 正式網站版本
- develop:長時開發版本,也就是正在進行中的所有開發
- symphony:官方倉儲中目前的穩定版本
- workspace:完全獨立出來的工作空間分支(孤兒分支?)
原文中 symphony 是使用 integration
分支,也就是官方進行中的下一版本。
注意: 最佳狀況其實是工作空間也有多個分支版本(配合不同的開發、測試與正式版本),像是官方工作空間那樣,擁有一個獨立的倉儲也是可以,但由於工作空間其實是以 submodule
掛進來的,很容易能讓不同環境指向不同版本(提交號),所以此處採用整合在同一倉儲的做法。
首先,開始調整各分支的名稱與對應。先提出 integration
分支的內容來:
git checkout integration
就那麼簡單而已,但各個外掛模組現在已經沒有同步了,試著檢查一下,輸入:
git status
應該會看到下列訊息:
# On branch integration
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: extensions/debugdevkit (new commits)
# modified: extensions/export_ensemble (new commits)
# modified: extensions/jit_image_manipulation (new commits)
# modified: extensions/markdown (new commits)
# modified: extensions/profiledevkit (new commits)
# modified: extensions/selectbox_link_field (new commits)
#
no changes added to commit (use "git add" and/or "git commit -a")
此時需要更新外掛模組:
git submodule update
系統應該會回應下列訊息:
Submodule path 'extensions/debugdevkit': checked out '4518a5cab0b15a3d08b972dd06d7fd5fa8c309aa'
Submodule path 'extensions/export_ensemble': checked out '64742947c11b9805105997d4482ccdf1e75c7b73'
Submodule path 'extensions/jit_image_manipulation': checked out 'f8f44259cc958ec9ec58a89709d920249ec5db89'
Submodule path 'extensions/markdown': checked out 'c967293ccbf34cf935ffe17d5a504a7ab31784d1'
Submodule path 'extensions/profiledevkit': checked out '0920617c7eadd8a1124d7c8d37be576a1fe4f848'
Submodule path 'extensions/selectbox_link_field': checked out 'dfda482a602304478d65c5f7d7677a0dbb1d1265'
目前的工作環境應該是乾淨、沒有待提交異動的,檢查一下:
git status
看起來像這樣:
# On branch integration
nothing to commit (working directory clean)
很好!由於我們目前使用 integration
分支進行開發,因此需要刪除原來安裝穩定版本的 master
分支,再把本地的 integration
分支改成 symphony
。讓我們先刪除 master
分支:
git branch -d master
應該獲得下列回應:
Deleted branch master (was a31d300).
接著,重新命名 integration
分支:
git branch -m integration symphony
看看目前本地的分支:
git branch -v
應該就只剩下一個從 integration
更名而來的 symphony
分支而已:
* symphony fce1b1d Tagging RC1
完美!
接著開始修理本地分支與遠端分支的對應,先檢查一下:
git remote -v
應該還是呈現當初克隆官方倉儲時的對應網址:
origin git://github.com/symphonycms/symphony-2.git (fetch)
origin git://github.com/symphonycms/symphony-2.git (push)
刪除掉 origin
遠端,改成對應自己的專案倉儲:
git remote rm origin
git remote add origin [email protected]:symphonycms/sym-getsymphony.git
為了後續的更新之用,重新把官方倉儲以 symphony
之名加回成遠端對應:
git remote add symphony git://github.com/symphonycms/symphony-2.git
再執行 git remote -v
會看到兩個遠端倉儲:
origin [email protected]:symphonycms/sym-getsymphony.git (fetch)
origin [email protected]:symphonycms/sym-getsymphony.git (push)
symphony git://github.com/symphonycms/symphony-2.git (fetch)
symphony git://github.com/symphonycms/symphony-2.git (push)
測試看看一切是否正確,symphony
分支應該要對應到 symphony
遠端(目前使用遠端的 integration 分支),因此要這樣輸入:
git pull symphony integration (是否應該加上 `-u` 建立追蹤關係?)
從更新中可以看到有部分外掛模組異動了:
remote: Counting objects: 52, done.
remote: Compressing objects: 100% (19/19), done.
remote: Total 38 (delta 27), reused 30 (delta 19)
Unpacking objects: 100% (38/38), done.
From git://github.com/symphonycms/symphony-2
* branch integration -> FETCH_HEAD
Updating fce1b1d..2409e9c
Fast-forward
extensions/jit_image_manipulation | 2 +-
symphony/assets/js/admin.js | 17 ++++++++++-------
symphony/content/content.blueprintsdatasources.php | 17 +++++++++++++++--
symphony/content/content.blueprintsevents.php | 12 ++++++++++++
symphony/lib/toolkit/class.lang.php | 10 ++++++----
symphony/lib/toolkit/fields/field.upload.php | 2 +-
6 files changed, 45 insertions(+), 15 deletions(-)
因此我們需要再次更新外掛模組。更新單一外掛模組的指令如下:
git submodule update extensions/jit_image_manipulation
呈現結果應該是這樣:
Submodule path 'extensions/jit_image_manipulation': checked out '5db9798dee8d6af515488b77bf969e08c96f4a68'
當已經準備好最新的官方更新之後,就可以根據目前分支來建立其他需要的分支了。先建立 master
分支:
git checkout -b master (根據 `symphony` 分支建立 `master` 分支,並切換過去)
正確的系統回應:
Switched to a new branch 'master'
接著再建立開發分支:
git checkout -b develop (根據 `master` 分支建立 `master` 分支,並切換過去)
應該看到了回應:
Switched to a new branch 'develop'
可以檢查看看本地端目前的所有分支:
git branch -v
現在我們有完全一樣的三個本地分支,都根據遠端倉儲 symphony
裡面的 integration
分支。
* develop 2409e9c Make the pagination disabled JS event more specific to handle when datasources are provided by extensions
master 2409e9c Make the pagination disabled JS event more specific to handle when datasources are provided by extensions
symphony 2409e9c Make the pagination disabled JS event more specific to handle when datasources are provided by extensions
建置 workspace
分支的工作將留到系統安裝程序完成之後才進行,安裝時會建立我們需要的 workspace
目錄結構。
此時可以將 master
與 develop
分支推送到專案遠端倉儲之中了:
git push origin master
應該要看到如下面的回應:
Counting objects: 24496, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (6527/6527), done.
Writing objects: 100% (24496/24496), 4.13 MiB | 21 KiB/s, done.
Total 24496 (delta 17937), reused 24387 (delta 17858)
To [email protected]:symphonycms/sym-getsymphony.git
* [new branch] master -> master
接著照樣將 develop
分支也推上去:
git push origin develop
這一步驟應該會一眨眼就完成,因為這些分支其實內容都是相同的。
注意: 我們並沒有推送 symphony
分支到專案倉儲,因為這個分支只用來更新 Symphony 核心程式,這個程序只會在本地環境中進行。
下一步,要來安裝 Symphony CMS 了。
在 Mac 上使用 Sequel Pro 管理 MySQL 資料庫,建立要用的兩個資料庫:
getsymphony_dev
getsymphony_local
依網頁指示循序安裝即可。
Symphony CMS 的 workspace
目錄會存放專案網站或應用程式的所有客製資訊,所有與製作網站相關的東西都可以擺在裡面。若是安裝了核心外掛模組以外的模組,最好是也在 workspace
目錄中記錄一下。(似乎可以使用 symphonyno5.sh
的 CSV 自動化模式,不過它是擺在網站的根目錄下。)
這裡的目標是維護一份「完整安裝檔(ensemble)」,遵循著 Symphony 安裝程式的路徑,外掛都是以 Git 模組的方式包含進來。此處同樣也會將 workspace
以外掛模組的模式處理。
注意: 外掛使用 Git 模組的方式,最危險的地方就是「相依性(dependency)」(這裡是說萬一該外掛被原開發者從 GitHub 上刪除,安裝時找不到對應下載的地方了)。因此保持一份完整安裝檔的全壓縮備份有其必要,必要時可以人工複製安裝。
在第一次乾淨安裝 Symphony 之後,一個具有下面次目錄結構的 workspace
目錄會被建立出來:
- workspace
- data-sources
- events
- jit-image-manipulation
- pages
- utilities
經由安裝程序,workspace
目錄被建立了,我們現在可以建立一個管理它的分支。要注意的是,這目錄下目前僅有一些空目錄的結構,裡面並沒有實際的檔案,由於Git並不會追蹤空目錄,若是此時建立就只會得到一個空倉儲。技巧是在每一個目錄下添加 .gitkeep
隱藏檔案,就不必添加不需要的奇怪檔案用於管理。
在終端機中切換到該目錄:
cd workspace
接著替每一個次目錄加入一個.gitkeep
隱藏檔:
touch data-sources/.gitkeep events/.gitkeep jit-image-manipulation/.gitkeep pages/.gitkeep utilities/.gitkeep
初始化:
git init
應該得到正確的回應:
Initialized empty Git repository in /Users/USERNAME/Sites/projects/getsymphony/dev/public/workspace/.git/
從 workspace
目錄執行 git status
應該獲得下列回應:
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# data-sources/
# events/
# jit-image-manipulation/
# pages/
# utilities/
執行 git add .
會加入目錄中所有檔案,檢查一下:
git status
下面是正確的系統回應:
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: data-sources/.gitkeep
# new file: events/.gitkeep
# new file: jit-image-manipulation/.gitkeep
# new file: pages/.gitkeep
# new file: utilities/.gitkeep
#
終於可以進行第一次的提交了:
git commit -m "Initialize workspace branch of the Symphony Network Ensemble"
系統給的正確回應:
[master (root-commit) 1257fcc] Initialize workspace branch of the Symphony Network Ensemble
0 files changed
create mode 100644 data-sources/.gitkeep
create mode 100644 events/.gitkeep
create mode 100644 jit-image-manipulation/.gitkeep
create mode 100644 pages/.gitkeep
create mode 100644 utilities/.gitkeep
預設是在 master
分支下,改名為 workspace
:
git branch -m master workspace
再檢查一下目前分支名稱:
* workspace 1257fcc Initialize workspace branch of the Symphony Network Ensemble
很順利。為了要能推到遠端,當然得先加入遠端倉儲的設定:
git remote add origin [email protected]:symphonycms/sym-getsymphony.git
將本地異動推到遠端倉儲(注意這是與前面使用的同一倉儲):
git push origin workspace
獲得系統回應:
Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 347 bytes, done.
Total 4 (delta 0), reused 0 (delta 0)
To [email protected]:symphonycms/sym-getsymphony.git
* [new branch] workspace -> workspace
注意: 這裡的操作很有意思,將 workspace
次目錄視為一個倉儲,推回與管理上層 Symphony 系統相同的遠端倉儲,成為一個獨立 workspace
分支。
現在,我們已經能夠將 workspace
目錄存成一個完整安裝檔了(為什麼只有該目錄?)。先改一下網站的名稱,打開 manifest/config.php
檔案:
###### GENERAL ######
'general' => array(
'sitename' => 'Symphony CMS',
),
########
修改網站名稱:
'sitename' => 'Symphony CMS',
改成:
'sitename' => 'Symphony Project',
儲存之後,開發後台頂端的名稱應該會立即變更。
從選單前往 System -> Preferences 頁面,按下 "Save Install Files" 按鍵。
在終端機中前往專案根目錄:
cd ~/Sites/projects/getsymphony/dev/public
檢查一下狀態, git status
,應該會看到下面的訊息:
# On branch develop
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: install/includes/config_default.php
# modified: install/includes/install.sql
#
no changes added to commit (use "git add" and/or "git commit -a")
兩個檔案異動了,檢查異動詳情可輸入:
git diff
按空白鍵向下捲動,按 q
跳出差異檢視視窗。
你也可以前往 workspace
目錄看看分支中的狀態:
cd workspace
git status
應該只會看到一項差異:
# On branch workspace
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# install.sql
nothing added to commit but untracked files present (use "git add" to track)
將 install.sql
加入 workspace
分支管理:
git add .
git commit -m "Export Ensemble: add install.sql file"
應該獲得下面的回應:
[workspace a2ccaff] Export Ensemble: add install.sql file
1 file changed, 163 insertions(+)
create mode 100644 install.sql
提交到遠端倉儲的 workspace
分支:
git push origin workspace
接著會到專案根目錄:
cd ..
我們接著要把 workspace
目錄變成一個Git模組,因此要先修改根目錄下的 .gitignore
檔案,不要再將 workspace/
排除:
.htaccess
workspace/
manifest/
install-log.txt
install/logs/
移除 workspace/
一行:
.htaccess
manifest/
install-log.txt
install/logs/
儲存 .gitignore
的修改後,就可以將 workspace
分支以模組方式加入了:
git submodule add git://github.com/symphonycms/sym-getsymphony.git workspace
得到回應:
Adding existing repo at 'workspace' to the index
執行 git status
指令,會顯示有兩項異動因為剛才運行 git submodule
指令而被暫存、等候提交:
# On branch develop
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: .gitmodules
# new file: workspace
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: .gitignore
# modified: install/includes/config_default.php
# modified: install/includes/install.sql
#
再把其他檔案也一併加入暫存:
git add -u
執行 git status
檢查一下待提交的異動:
# On branch develop
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: .gitignore
# modified: .gitmodules
# modified: install/includes/config_default.php
# modified: install/includes/install.sql
# new file: workspace
#
這一次我們要使用多行註解模式的提交記錄,輸入下面指令、叫出預設編輯器(vi):
git commit
輸入下面的註解:
Initialize Symphony Project Ensemble
Modify the .gitignore files, update the install files and include the workspace directory as a submodule
按 ESC 鍵並輸入 :wq
儲存並退出 vi:
[develop b1fbac0] Initialize Symphony Network Ensemble
5 files changed, 119 insertions(+), 109 deletions(-)
create mode 160000 workspace
把新提交推送到遠端,我們就完成了專案的第一個自動安裝程序了。
git push origin develop
疑問:
workspace
目錄沒有刪除後再加入,添加分支模組時也沒有輸入指定分支,是會抓取目前workspace
目錄的設定?(該目錄是處於對應遠端workspace
分支的狀態。)- 在同一個倉儲之下,分支的整個檔案結構完全不同,這樣的方式與獨立一個外部倉儲,究竟何者較優?
要讓自動安裝程序較為完整,最好是加入說明檔案。切換到 workspace
目錄, touch README.md
添加說明文件檔(最好是遵循 Markdown syntax )。
完成之後,記得提交並推送到遠端倉儲:
git add .
git commit -m "Add README file"
git push origin workspace
應該會回應:
Counting objects: 15, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 1.73 KiB, done.
Total 8 (delta 3), reused 0 (delta 0)
To [email protected]:symphonycms/sym-getsymphony.git
2409e9c..b1fbac0 develop -> develop
注意,必須要讓專案上層也知道模組倉儲有了變化,切換到上層目錄:
cd ..
輸入 git status
檢查一下狀態:
# On branch develop
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
# (commit or discard the untracked or modified content in submodules)
#
# modified: workspace (new commits)
#
上層確實已經察覺到模組有了變化(新的提交),若是異動並未提交,就會顯示:
# modified: workspace (untracked content)
因此趕緊將異動後的 workspace
目錄加入暫存、提交並推送到遠端:
git add workspace
git commit -m "Update the workspace submodule: Add README file"
git push origin develop
上面的範例展示了後續更新的正常流程。
測試一下 Ensemble 能否正常運作,使用先前建立的虛擬站點(virtual host) myproject.local
,前往該目錄,刪除掉系統預裝的 index.html
(因為無法複製倉儲到一個有檔案的目錄)。
cd ~/Sites/projects/getsymphony/local/public
rm index.html
接著複製倉儲,使用 --recursive
選項一併檢查下面的外掛模組,指定 develop
分支而不要複製預設的 master
分支:(這行指令要背起來:遞迴模組、指定分支,還是從已建立的目錄下進行複製。)
git clone --recursive --branch develop git://github.com/symphonycms/sym-getsymphony.git .
打開瀏覽器、前往安裝頁面,測試是否能夠正常安裝。
透過 Git 開發 ensemble 時,偶爾會發生失誤、未如計劃運作,因此極有可能需要回復到之前的某個狀態,當一切錯誤還沒有發生的那個時點。
搭配匯出 Ensemble 的外掛,確實有可能持續儲存資料庫的異動、提交這些異動到版本管理系統之中(因為 Export Ensemble 會製作資料庫的安裝檔 install.sql
)。但由於該檔案是記錄在 SQL 檔案中的資料庫語法,沒辦法把資料也一併匯入資料庫。安裝程序就只會從頭安裝 Symphony,這也意味著重新安裝必須移除一些檔案與資料庫記錄:
- Remove
.htaccess
file - Remove
manifest
directory - Remove all database tables
若是我們需要重新安裝,可以從專案根目錄執行:
sudo rm -rf .htaccess manifest
接著刪除所有資料庫中的資料表,回到瀏覽器的安裝畫面重來一次。這是必要的程序,因為許多資料必須從安裝畫面、過程中重新建立,包含了 manifest
下面有隱私議題的安裝設定檔、第一名管理者帳號密碼、主機的基礎設置等等。
這實在是個痛苦的流程。
若是能將 SQL 資料匯出到一個檔案、將這個檔案擺進版本管理系統,當我們需要回復到某個時點,就有可能檢出那個提交、移除資料庫表單,從那一次的提交資料中匯入到資料庫。Dump DB 外掛滿足了這個需求,提供了一個界面能將內容資料與管理者資料分別儲存到不同的文件。這讓我們有了選擇,開放資料可以只使用 data.sql
,私密倉儲才擺放管理者資料,一般的 Ensemble 做不到這一點,因為它會移除管理者資料(author data)。
注意不要分享 Dump DB 外掛建立的 author.sql
到開放倉儲,裡面可是有管理者帳號密碼等隱私資料。
首先是安裝 Dump DB 外掛,切換到專案根目錄:
cd ~/Sites/projects/getsymphony/dev/public
將 Dump DB 外掛以 Git 模組方式加入:
git submodule add git://github.com/nils-werner/dump_db.git extensions/dump_db
提交更新:
git commit -m "Add Dump DB extension as a submodule"
前往開發者後台,管理外掛的頁面,啟用 Dump DB。
還需要調整一下 Dump DB extension 的設定,這得修改 manifest/config.php
檔案,在最下方加入:
###### DUMP_DB ######
'dump_db' => array(
'last_sync' => '2013-02-28T10:56:51-08:00',
'path' => '/workspace/sql',
'restore' => 'yes'
),
########
接著建立儲存目錄:(注意這個指令)
git mkdir workspace/sql
因為我們在本地端工作,可以藉著修改 .git/config
檔案避免掉檔案權限也被列入追蹤的問題。在檔案頂端應該會看到:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = false
把 filemode
設定修改成 false
filemode = false
這樣一來,Git 將會在檢出工作樹中的異動檔案時,忽略掉 Unix 權限的設定。
當在本地工作時,Dump DB 或是匯出 Ensemble 檔案,可以授與完全開放的權限:
sudo chmod -R 777 install
sudo chmod 777 workspace/install.sql
在遠端的正式機或開發主機上,要注意權限的安全設定。當然為了安全,正式機應該完全移除掉安裝檔案。
此時到 Symphony 開發者後台的選單 System > Preferences 頁面,點擊 Dump 資料庫的 "Save Data" 按鍵,還有匯出 Ensemble 區塊的 "Save Install Files" 按鍵。
回到終端機,切換到 workspace
目錄,暫存 install.sql
檔案以及 sql
目錄,並進行提交。
cd workspace
git add install.sql sql
執行 git status
檢查一下回應:
# On branch workspace
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: install.sql
# new file: sql/data.sql
#
提交異動並推送到遠端倉儲:
git commit -m "Add SQL files after installing Dump DB extension"
git push origin workspace
再回到專案根目錄,暫存 install
與 workspace
目錄並提交:
cd ..
git add install workspace
git status
系統應該如此回應:
# On branch develop
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: install/includes/config_default.php
# modified: workspace
#
提交異動、記錄 workspace
模組的狀態,同時也將自動安裝檔推送到遠端。
git commit -m "Update install files and workspace submodule after installing Dump DB extension"
git push origin develop
我們可以在本地端進行測試,使用 getsymphony.local 的虛擬站點,切換到專案根目錄,從 origin
遠端拉回 develop
分支,更新外掛模組:
cd ~/Sites/projects/getsymphony/local/public
git pull origin develop
git submodule update --init
只有等到 Dump DB 外掛已經啟用後,才能使用它的更新資料庫功能。重新安裝修改過的 Ensemble,我們才能含入替 Dump DB 外掛調整後的設定。
先刪除舊的安裝:
sudo rm -rf .htaccess manifest
接著移除 getsymphony_local
MySQL 資料庫,再次從瀏覽器前往安裝畫面。
若是一切順利,前往外掛管理頁面,應該會看到 Dump DB 已經啟用。
建立一些頁面,讓資料庫進行變化:
- Page Settings > Title:
Home
- Page Settings > Page Type:
index
回到管理頁,儲存資料庫檔案,並匯出 Ensemble。
在終端機中前往 workspace
目錄:
cd ~/Sites/projects/getsymphony/dev/public/workspace
使用 git status
檢查一下目前狀態:
# On branch workspace
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: install.sql
# modified: sql/data.sql
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# pages/home.xsl
no changes added to commit (use "git add" and/or "git commit -a")
暫存異動:
git add .
各項異動應該就等候提交了:
# On branch workspace
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: install.sql
# new file: pages/home.xsl
# modified: sql/data.sql
#
提交異動到 workspace
分支:
git commit -m "Add Home page and update SQL files"
系統回應:
[workspace 6737b64] Add Home page and update SQL files
3 files changed, 22 insertions(+), 2 deletions(-)
create mode 100644 pages/home.xsl
推送提交到 origin
遠端( workspace
分支):
git push origin workspace
系統回應:
Counting objects: 12, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (7/7), 1.14 KiB, done.
Total 7 (delta 3), reused 0 (delta 0)
To [email protected]:symphonycms/sym-getsymphony.git
fac240c..6737b64 workspace -> workspace
回到上層專案檢查狀態:
cd ..
git status
將會看到:
# On branch develop
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: install/includes/config_default.php
# modified: install/includes/install.sql
# modified: workspace (new commits)
#
no changes added to commit (use "git add" and/or "git commit -a")
使用 git diff
觀察異動詳情。
若一切順利,就可以提交並推送到遠端 origin
了:
git add install workspace
git commit -m "Update workspace submodule and install files after adding Home page"
git push origin develop
切換回正式網站,檢出剛剛做的異動:
cd ~/Sites/projects/getsymphony/local/public
git pull origin develop
git submodule update
因為並沒有新的外掛模組需要安裝,可以省略 --init
選項,使用 git submodule update
即可。
剩下最後一步:前往 System > Preferences 頁面回復資料庫。從 Dump Database 區塊點擊 "Restore Data" 按鍵,會顯示下面警示:
The page at getsymphony.local says:
Do you really want to overwrite your database with the contents from the file?
按下 "OK" 按鍵,頁面頂端會提示資料庫已經回復的字樣。
Data successfully restored from /workspace/sql/data.sql in 68 queries.
注意我們也添加了首頁到 Blueprints > Pages,因此瀏覽網站應該要看到新的首頁。
至此,我們就有了一整組使用 Git 管理的開發、測試與上線流程。
重要注意事項: 上面的流程,實際上無法顧及正式上線站台之中,由終端使用者產生的資料。由於 Dump DB 外掛會使用一系列的 INSERT
陳述來回復資料庫,正式站台若有新增或刪除資料庫內容,回復程序可能會因為不同的 AUTO_INCREMENT
值而造成資料浩劫。Dump DB 外掛在開發環境中,可以很好的處理資料庫持續增加結構性變化的需求,例如建立了新的 Ensemble 或新的頁面,但是,萬一你刪除了一個資料表,Dump DB 回復程序無法處理那些被刪除的資料列,你可能需要手動移除受影響的資料表,然後使用 SQL 檔案人工回復。這流程是好不容易才嘗試出來的,當我對一個 Ensemble 進行結構性變化時,我總會儲存一次 Ensemble 和 Dump DB SQL 檔案,萬一出事了,我就可以從歷史記錄中回復到之前的某一版本。
對一個正式上線的網站,流程應該反過來,正式主機中的資料必須第一優先維持。為了讓開發環境與正式主機之間資料庫的同步,強烈建議使用 Database Synchroniser 或是 Continuous Database Integration 。
替網站建立了完整的導覽頁面組:
- Stream
- Discussions
- Questions
- Blog
- Showcase
- Events
- About
接著就必須儲存 Dump DB 資料與匯出 Ensemble 安裝檔案(在開發後台中按鍵執行)。
在 workspace
分支中提交頁面模板:
cd workspace
git add pages
git commit -m "Create pages for main navigation"
在 workspace
分支中提交資料庫的異動,推送到遠端:
git add .
git commit -m "Update SQL files after creating main pages"
git push origin workspace
回到專案根目錄,提交工作區異動以及 Ensemble 檔案,推送到遠端 develop
分支:
cd ..
git add -u
git commit -m "Update workspace: Create main navigation pages"
git push origin develop
將 Symphony Factory framework 的 development
分支,加入成 workspace
的模組:
cd workspace
git submodule add --branch development git://github.com/symphonycms/factory.git factory
git commit -m "Add development branch of the Symphony Factory framework as a submodule"
git push origin workspace
Fix the HTML repository to more closely match templates for portability to Symphony. Make modifications to the templates to enable the layout in Symphony, using flat XML files until sections, fields and data sources have been configured.
Disable the Symphony Network navigation links until the sites are ready to be connected.
Push the develop
and workspace
branches to the origin
.
Test the updates in the local
virtual host. It is important to include the --recursive
option when updating the submodules because the workspace
branch now contains a submodule for the Symphony Factory framework.
cd ~/Sites/projects/getsymphony/local/public
git pull origin develop
git submodule update --init --recursive
Navigate to the System > Preferences page and click on the Dump DB "Restore Data" button.
The main navigation for the Community site is working.
Now, we are ready to collaborate on the Network sites!