本篇參考:https://architect.salesforce.com/decision-guides/migrate-change
https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_dev2gp.htm
很偶然看到了這篇文章,一下子就被吸引住了。儘管專案中的一些部署方式有用到過,考SF認證也有很多相關的靠題,也能二二三三的講出點不同場景以及優缺點,但總不是很全面的瞭解,所以基於這篇進行一下翻譯,也順便讓自己學習一下了。英語好的,直接看原文即可。
背景: 我們做專案不管是國內專案還是對日歐美專案,除了開發以外,少不了的要部署。可能針對一個欄位的建立,直接生產建立,然後手動設定了FLS,或者部署一個 report type / report基於change set,又或者需要刪除一個 apex class,通過 metadata api,比如使用ant,又或者是一個一兩年的大型專案,使用 CI + CD的metadata api 部署。當然國內專案大部分都是二次開發為主,如果你是一個ISV,可能還要用到 managed package等等,那什麼時候用到哪種部署方式呢? 作為新手可能想著是專案規定的,如果作為老手的話,還是可以基於官方的 best practice來進行一些參考,按照官方的建議,有七種不同的部署選項,從簡單但不太可延伸的技術到更復雜但高度可延伸的方法依次是:
1. Manual Changes in Production
2. Change Sets
3. Metadata API: Direct Deployments
4. Metadata API: Deployment with Source Control + Continuous Integration
5. Org Dependent Packages
6. Unlocked Packaged
7. Managed Packages
下圖中從左到右代表著部署方式更加的可延伸性。可延伸性意味著支援:
- 更多變化的更大部署
- 更多的團隊或更大的團隊同時處理更多的專案
- 更多的測試和自動化,實現更頻繁的部署
- 更加一致和可靠的部署
當然,在實際的專案中或者工作中,並不一定要求更高的可延伸性,因為需要可延伸性,一定需要犧牲或者需要付出一些東西,比如:
- 放棄一些簡單性,但獲得更多可延伸性
- 需要提高所需的技術技能水平
- 將更多的時間花在流程上,而不是產品上
至少對於目前的場景來說, change set / metadata api / CI & CD metadata api可以搞定大部分專案的需要。
以下例舉的是不同的部署模式所支援和不支援的選項。
1.Org-dependent package是Winter '21 release釋出的測試版。
2.即使不使用scratch org建立包,它也必須能夠部署到scratch org,否則包建立將失敗。
3.每個依賴項必須在包中或另一個包中。
4.可以通過命令上的標誌跳過包版本建立時的驗證,以減少包構建時間。
後續內容是針對不同的場景下,每種部署方式的限制,優缺點(何時選擇,何時不選擇)以及如何減輕部署的風險。
一. Manual Change In Production
1. 限制: 最大的限制莫過於沒法直接更改 apex class,實際專案中很少會遇見不更改 apex class的專案,所以如果有 apex class相關的更改,則忽略此種方式。
2. 什麼場景下選擇此種部署方式(優點):以下場景可以參考。
- 針對一些型別的 metadata type,目前只支援 manual deploy.
- 在業務的敏捷上是一種可以接受並且風險小的metadata, 比如 Report / ListView等。
- 針對小的變動,部署會特別快。比如要緊急關閉一個validation rule,或者針對一些許可權的分析,可能需要臨時建立 permission set測試一下許可權,測試完成以後會刪除這種。
- 如果在salesforce上線前第一次設定,在風險較低的情況下,並且在使用者存取系統之前,有一個認真的測試計劃,這將非常方便。比如生產環境先啟用 enable account team或者 enable community等設定可以在專案最開始的時候,生產環境手動設定上。
3. 什麼場景下不建議選擇此種部署方式。以下場景可以參考。
- 許多型別的更改都是極其危險的:比如validation rule的條件,大於號寫成了小於號。AND寫成了OR,直接在生產環境操作這種都是極其危險的。
- 生產的metadata change很難進行測試。
- 對於一個團隊來說不適合於擴充套件。比如平臺有 sales cloud以及 service cloud並且兩個cloud由兩個團隊來開發,兩個團隊都會用到 person account表,針對欄位以及其他共用的情況就很容易出現衝突情況。
- 很難撤回或者放棄一些change。
- 當有客戶在系統上時,很難部署大量的、複雜的更改。
4. 減輕手動更改可能面臨的風險:如果有隻能手動完成的更改,則可以通過首先在sandbox中完成更改的步驟,測試結果,然後在生產中重複相同的一系列步驟來驗證這些更改。總體來說就是在sandbox多測試。
二. Change Set
此種部署方式應該是小型專案中經常遇見的方式。
1. 限制:
- change set只能和 sandbox一起搭配使用,並且sandbox只能從production org來建立。
- 可以單擊View/Add Dependencies按鈕來查詢依賴項,但它可能無法捕獲所有內容。舉個例子,我們有一個Apex類,該類對其測試類沒有正式的依賴關係,但我們在部署時必須具有測試覆蓋率,因此如果不包含測試,則某個更改集將無法部署。在點選這個按鈕時,這個測試類不會被自動捕獲。
- 最多隻能展示10000個檔案。(由核取方塊表示的專案)
- 有時,sandbox位於與目標組織不同的版本上。當這種情況發生時,某些metadata型別無法部署.
- changeset沒法刪除任何metadata或設定。
2. 什麼場景下選擇此種部署方式(優點):以下場景可以參考。
- 它已經存在/執行了很長時間,所以大多數人都很熟悉它。
- 基於UI操作,admin操作友好。
- 與手動執行的更改不同,change set的更改同時影響生產,沒有時延問題。
- 驗證和部署時間可以有區別。比如週五在大家都在上班時驗證好,週末進行部署操作。
- 驗證/部署失敗時,可以克隆 change set從而減少很多時間。
- 如果通過manual change做了一些緊急的變更,可以通過 change set同步到 sandbox。
- 方便追蹤這些change 如何在不同的環境中的移動。
- 可以有許可權來設定誰可以建立和部署 changeset。
3. 什麼場景下不建議選擇此種部署方式。以下場景可以參考。
- 在構建過程中,您必須跟蹤您的更改。針對metadata,我們希望tracking什麼時候誰更改。
- 如果我們在部署時,需要dev->sit->uat->prd,那麼所有的 changeset都需要重新打包。
- 不是所有的 metadata都支援change set部署,比如 community相關,對 changeset支援就基本不可以。
- changeset打包傳送是有時延的,從A sandbox到B sandbox不是實時就upload成功,可能需要幾分鐘或者幾小時,不可保證。
4. 基於changeset部署轉向到基於 metadata 部署:如果你的團隊一直在使用change set,但正在考慮轉移到基於原始碼的部署,則可以通過Salesforce CLI檢索change set。然後,一個CLI使用者或指令碼可以使用CLI命令通過名字檢索change set並提取source。在這種情況下,我們便不使用 changeset方式進行部署,而是基於 metadata deploy方式。
三. Metadata API: Direct Deployments
Salesforce Metadata API 允許我們遷移metadata。當然我們實際場景中很少直接用 Metadata API,而是使用Ant指令碼或者CLI。通過基於metadata部署方式,我們只需要針對我們想要部署的資源來新增或者修改即可。部署也只針對我們整理的資源,其他不在package.xml或者不在整理中的資源不會做任何操作。
1. 限制:
- 與change set類似,每個事務只允許最多10000個檔案。
- 檔案的總解壓縮大小不能超過400MB。
- metadata api 不支援所有的metadata型別。
2. 什麼場景下選擇此種部署方式(優點):以下場景可以參考。
- 部署可以重複使用。資源可以重複部署使用,比如 dev->sit->uat,就可以使用同一個包進行部署
- 可以刪除資源,比如刪除 apex class
- 可以部署settings型別。舉個例子,有些功能在PROD沒有啟用,你可以通過metadata部署方式進行啟用和設定。
- 可指令碼化。可以建立可重複的部署指令碼,以確保這些項在部署之前和/或之後處於正確的狀態。
3. 什麼場景下不建議選擇此種部署方式。以下場景可以參考。
- 很難進行追蹤。比如我們想回滾到什麼樣的節點,我們不清楚這個期間誰進行過什麼樣的部署。
- 很難進行控制。多個開發人員如果部署,可能造成獲取的資源不同的版本,容易進行覆蓋操作。
4. 減輕手動更改可能面臨的風險:部署人員減少,找專人進行部署,當然這個在減輕風險的情況下,也可能出現瓶頸問題。
四. Metadata API: Deployment With Source Control And Continuous Integration
這種部署方式應該是作為開發人員最舒服的方式,程式設計師只需要關注自己的功能做好,然後建立自己的分支,上傳自己的資源,merge到主分支即可。部署人員通過CI/CD的一些工具(Jenkins,dockers等)即可進行持續繼承持續部署。
1. 限制(和第三個相同):
- 與change set類似,每個事務只允許最多10000個檔案。
- 檔案的總解壓縮大小不能超過400MB。
- metadata api 不支援所有的metadata型別。
2. 什麼場景下選擇此種部署方式(優點):以下場景可以參考。
- 原始碼控制是一個已解決的問題。許多公司已經為原始碼控制和CI建立了高質量的工具。
- 開發人員知道它。這是Salesforce之外的開發者的預設操作模式。
- 支援自動化。從GitHub行動中進行部署,或者讓你的CI系統訂閱webhooks來進行這些行動。除了部署,這還允許測試自動化、程式碼分析和linter/styling來檢查。
- 對於大專案來說,可延伸性更好。
- 分支有助於多個專案同時進行。即使在一個小團隊中,你也可能同時有小功能、緊急情況、釋出檢查、錯誤修復、實驗和大型專案的混合。把它們組織起來有助於你的團隊更快地工作。
- 分支允許部分部署。假設多個分支情況下,如果測試人員只測試完成部分功能,可以支援部分功能對應的分支部署。
3. 什麼場景下不建議選擇此種部署方式。以下場景可以參考。
- 你的團隊自定義內容很多的metadata type不支援metadata api部署或者部署的不是很好。
- 對你的團隊來說,原始碼控制是一個未知的領域。
- 公司的釋出通常是大型的,而且不頻繁。
- 沒有能力投入時間來建立這種工具。
以下內容講的是基於包的部署,那先來說一下包(package)的背景。
Salesforce自AppExchange推出以來就一直使用軟體包,大多數管理員都熟悉在環境中安裝的各種 managed package,比如conga什麼的。第一代管理包主要是為這種ISV使用情況設計的。管理包的限制性很強;一旦你釋出了一個包,有很多改變就不再被允許,因為開發者無法知道客戶組織可能建立了什麼依賴關係。也有一些客戶使用非管理型軟體包,這些軟體包是不可能升級的。
第二代軟體包是從原始碼建立的,而不是從一個org的內容中建立的。現在的官方檔案中,除了特意說明是第一代管理包之外,其他的說的package都是二代包(second-generation package),官方也建議除歷史情況,否則都使用二代包。針對二代包的情況下,我們常說的有兩種: unlocked & managed。接下來進入包部署的這幾種情況。
包的基礎知識
包的概念是有一個是有版本的metadata的子集。擁有以下特性
- 你可以升級到一個包的較新版本,或者在某些情況下恢復到以前的版本。
- 你可以乾淨地解除安裝一個包,而不需要知道其中的所有內容。
- 你可以從一個包中刪除一些後設資料,當包被安裝時,後設資料就會從org中刪除。
- 包可以建立在其他包的基礎上,並有明確宣告的依賴關係。
- 包使得在多個組織間共用程式碼變得容易。
其他知識如下:
- 當你建立一個軟體包版本時,該版本開始處於Beta狀態。你可以將軟體包安裝在Scratch orgs和sandbox中,但不能直接安裝在生產環境中。要在生產中部署,你必須首先將軟體包提升到釋出狀態。通過控制這個階段,軟體包可以方便地測試以及受控的釋出。
五. Org-Dependent Packages
Org-dependent 包在技術上是在建立時帶有特殊標誌(-skipvalidation)的unlocked package。它們依賴你的組織中的某些東西。比如你的 package的資源有一個flow,flow參照了自定義的notification type,這個 notifycation type還不支援打包。這種場景下這個包部署在你的環境中,只能樂觀的認為你的環境存在 notification type。如果不存在,則丟擲自定義異常。
1. 限制:
- 其他的package不能依賴於 org-dependent package;
- org-dependent package 不能依賴於其他的package。
2. 什麼場景下選擇此種部署方式(優點):以下場景可以參考。
- 你想要建立一個 package,這個package依賴於沒有package支援的東西。
- 你在org中有一些後設資料,還沒有準備好被打包。例如,它有一些糾纏不清的迴圈依賴關係,使得這個過程很困難。
- 你想要一些packaging的好處,但卻不能控制你所依賴的後設資料(例如,它被你公司的另一個團隊所擁有)
- 你想要一些打包的好處,但你不能將你現有的後設資料模組化
- 你可以在現有的未打包的後設資料上進行部署
- 你無法建立一個支援你的包的內容的scratch org,即使它沒有外部依賴性。因為依賴於org的包跳過了在scratch org中驗證包的步驟,你可以用它們來解決這個限制。
3. 什麼場景下不建議選擇此種部署方式。以下場景可以參考。
- 如果你的軟體包可以包含/宣告所有的依賴關係,那麼最好選擇unlocked package。你可以避免部署時出現意外的錯誤。
- 你希望能夠將軟體包部署到一個scratch org。例如,你有使用scratch orgs的自動CI測試。Org-dependent 的包必須進入某種型別的sandbox,在那裡滿足依賴性,這可能需要更長的時間來建立,並且不能立即銷燬。
- 所有的包都需要大量的時間來建立、釋出和安裝。
注: 老實說,專案中還沒有用到過 Org-dependent package,感覺這種大部分場景都可以被 unlocked package取代而且unlocked package還很好使用。
六. Unlocked Packages
1. 限制:
- 依賴關係圖中的所有東西都必須是可打包的,已打包的,並在依賴關係清單中。
- 你必須能夠設定一個 scratch org 來支援你的包所需要的一切。
- 75%的最低Apex測試覆蓋率。
2. 什麼場景下選擇此種部署方式(優點):以下場景可以參考。
- 它提供了你的metadata的一個已知的、良好的狀態。
- 你知道metadata在任何時間點的確切狀態。該組織有一個軟體包版本部署的記錄,並且軟體包與源控制相聯絡。
- 包可以被部署到Scratch org進行測試。
- 你可以恢復到以前的版本。
- 你可以在unpackaged 的metadata上進行部署。
3. 什麼場景下不建議選擇此種部署方式。以下場景可以參考。
- 生產上的metadata change會被新的軟體包部署所覆蓋。
- 大型重構可能導致你無法升級的情況。
- 所有的包都需要大量的時間來建立、釋出和安裝
4. 減輕手動更改可能面臨的風險:對於打算用於非生產環境的軟體包,你可以跳過軟體包驗證步驟在新視窗開啟連結。這加快了打包過程,所以你可以更快部署並獲得測試結果。如果你正在使用自動化測試和頻繁的構建,這可能是有用的。
七. Managed Packages
Managed Package比Unlocked Package有更多的限制。它們通常是由AppExchange的合作伙伴使用的,他們希望防止客戶在設計時沒有被依賴的程式碼或元件上建立依賴關係。
1. 限制:
- 一旦你暴露了一些東西,就很難將其刪除(打包時假設可能有你不知道的依賴關係)。
- 你需要一個與你的Dev Hub相關的名稱空間,任何參照包的程式碼都需要在參照中使用該名稱空間。
2. 什麼場景下選擇此種部署方式(優點):以下場景可以參考。
- 你是一個希望在AppExchange上構建和提供打包解決方案的合作伙伴。
- 你正在多個org工作,並正在建立一個用於這些組織的軟體包,而且你有一個迫切的需求,即阻止生產中的變化,這不能僅僅通過治理和許可權來實現。
- 你有一個迫切的需求來正式確定一個包所暴露的內容,並更好地封裝一些內部因素,而這些因素無法通過解鎖包的同等能力來滿足。
- 你迫切需要存取名稱空間,以幫助保持程式碼的組織性和模組化,這不能僅通過治理和開發標準來實現,並且有足夠的工程專業知識來設計增加的複雜性,如LWC跨名稱空間操作在新視窗開啟連結。
3. 什麼場景下不建議選擇此種部署方式。以下場景可以參考。
- 你不是AppExchange的合作伙伴,也沒有令人信服的理由去使用它們。
- 你不能100%確定後設資料如何被重用,並且不想阻止所有的重用。
- 包的功能經常變化或可能需要允許重大的重構。例如,一些用於處理安全或快取的自定義Apex實用程式可能比密集的業務邏輯更適合。
- 你的團隊對如何為包的開發者和使用者設計額外的名稱空間相關的複雜性沒有絕對把握。這在使用動態程式碼或設定的地方尤其如此。
- 所有的包都需要大量的時間來建立、釋出和安裝。
總結:上述內容為SF官方整理的一些部署方式以及這些部署方式的適用場景以及不適用場景。文中後續還有很多其他知識的介紹,感興趣的小夥伴可以自行檢視。我們實際專案中,可能manual / changeset/ metadata部署使用的較多。基於 package的話 unlocked package偶爾也會使用。其他兩種目前本人還沒有使用過,當然好的部署模式不如好的部署習慣。找一個自己最擅長的,最不出錯的更佳。篇中有錯誤地方歡迎指出,有問題歡迎留言。