管線快取
Azure DevOps Services
管道快取可以透過允許先前執行的輸出結果或已下載的依賴項在後續執行中重複使用,以此來減少或避免重新創建或重新下載相同檔案的成本,從而縮短建置時間。 在每次執行開始時反覆下載相同相依性的情況下,緩存特別有用。 這通常是一個耗時的過程,涉及數百或數千個網路呼叫。
快取可以在改善建置時間時生效,前提是還原和儲存快取的時間小於從頭開始產生輸出的時間。 因此,快取在所有案例中可能都無效,而且實際上可能會對建置時間產生負面影響。
注意
傳統發行管線不支援管線快取。
使用構建產物或是快取的時機
管線快取和 管線成品 執行類似的功能,但專為不同的情境所設計,不應互換使用。
當您需要擷取一個作業中產生的特定檔案,並與其他作業共享它們時,請使用管線成品(而其他作業可能會失敗而沒有它們)。
如果您想要透過重複使用先前執行的檔案來改善建置時間,請使用管線快取 ,而即使沒有這些檔案,也不會影響作業的執行能力。
注意
管道快取和管道成品對所有等級(免費和付費)都是免費的。 如需詳細資訊,請參閱 成品記憶體耗用量。
快取工作:運作原理
新增至管線的快取是使用 快取工作。 此工作的運作方式就像任何其他工作一樣,而且會新增至作業的 steps
區段。
在執行期間遇到快取步驟時,工作會根據提供的輸入還原快取。 如果找不到快取,步驟就會完成,而作業中的下一個步驟會執行。
在所有作業步驟執行完畢,並假定作業狀態為 成功 之後,系統會自動為每個未略過的 「還原快取」 步驟新增並觸發特殊的 「作業後:快取」 步驟。 此步驟負責 儲存快取。
注意
快取是不可變的,這表示一旦建立快取,其內容便無法變更。
設定快取工作
快取工作 有兩個必要參數:索引鍵 和 路徑:
-
路徑:要快取的資料夾路徑。 可以是絕對路徑或相對路徑。 相對路徑是相對於
$(System.DefaultWorkingDirectory)
解析的。
注意
您可以使用 預先定義的變數 來儲存您要快取之資料夾的路徑,不過不支援通配符。
-
鍵:應設定為您要還原或儲存之快取的識別碼。 索引鍵是由字串值、檔案路徑或檔案模式的組合所組成,其中每個區段會以
|
字元分隔。
字串:
固定值(例如快取的名稱或工具名稱)或取自環境變數(例如目前的 OS 或目前的作業名稱)檔案路徑:
內容將被哈希處理的特定檔案路徑。 此檔案必須在工作執行時存在。 請記住,「看起來像檔案路徑」的任何 索引鍵區段都會被視為檔案路徑。 特別是,這包括包含.
的區段。 當這個「檔案」不存在時,這可能會導致工作失敗。提示
若要避免將類似路徑的字串區段視為檔案路徑,請使用雙引號來包裝它,例如:
"my.key" | $(Agent.OS) | key.file
檔案樣式:
Glob 樣式通配符模式的逗號分隔清單,必須符合至少一個檔案。 例如:-
**/yarn.lock
:來源目錄下的所有 yarn.lock 檔案 -
*/asset.json, !bin/**
:來源目錄下目錄中的所有 asset.json 檔案,但 bin 目錄下除外
-
檔案路徑或檔案模式所識別之任何檔案的內容會哈希以產生動態快取索引鍵。 當您的專案中含有可唯一識別正在快取之內容的檔案時,這會非常有用。 例如,package-lock.json
、yarn.lock
、Gemfile.lock
或 Pipfile.lock
等檔案通常會在快取索引鍵中參考,因為它們全都代表唯一的相依性集。
相對檔案路徑或檔案模式會針對 $(System.DefaultWorkingDirectory)
解析。
範例:
以下範例顯示如何快取 Yarn 所安裝的相依性:
variables:
YARN_CACHE_FOLDER: $(Pipeline.Workspace)/s/.yarn
steps:
- task: Cache@2
inputs:
key: '"yarn" | "$(Agent.OS)" | yarn.lock'
restoreKeys: |
"yarn" | "$(Agent.OS)"
"yarn"
path: $(YARN_CACHE_FOLDER)
displayName: Cache Yarn packages
- script: yarn --frozen-lockfile
在此範例中,快取索引鍵包含三個部分:靜態字串(“yarn”),作業執行所在 OS,因為此快取是每個操作系統唯一的,以及可唯一識別快取中相依性集的 yarn.lock
檔案哈希。
在新增工作之後的第一次執行中,快取步驟會報告「快取遺漏」,因為此索引鍵所識別的快取不存在。 在最後一個步驟之後,將會從 $(Pipeline.Workspace)/s/.yarn
中的檔案建立快取並上傳。 在下一次執行時,快取步驟會報告「快取命中」,並下載並還原快取的內容。
使用 checkout: self
時,存放庫會被檢出至 $(Pipeline.Workspace)/s
,且您的 .yarn
資料夾通常位於存放庫本身。
注意
Pipeline.Workspace
是執行管線之代理程式的本機路徑,其中會建立所有目錄。 此變數的值與 Agent.BuildDirectory
相同。
若使用其他任何不是 checkout: self
的選項,請務必更新變數 YARN_CACHE_FOLDER
,因為它應指向 .yarn
所在的存放庫。
還原金鑰
如果想要查詢多個確切索引鍵或索引鍵前置詞,則可以使用 restoreKeys
。 這是在 key
未能匹配時,用來回退到另一個鍵。 回復密鑰會依前綴搜尋密鑰,並返回最新建立的快取條目。 如果管線找不到完全相符的結果,但想要使用部分快取叫用,這非常有用。 若要插入多個還原密鑰,請使用新行來指出還原密鑰來分隔它們(如需詳細資訊,請參閱範例)。 將按照從上到下的順序嘗試還原金鑰。
自託管代理程式所需的軟體
封存軟體/ 平臺 | 窗戶 | Linux | Mac |
---|---|---|---|
GNU Tar | 必填 | 必填 | 不 |
BSD Tar | 不 | 不 | 必填 |
7-Zip | 推薦 | 不 | 不 |
上述可執行文件必須位於PATH環境變數中列出的資料夾中。 請記住,裝載的代理程序隨附隨附的軟體,這隻適用於自我裝載的代理程式。
範例:
以下是如何使用 Yarn 還原金鑰的範例:
variables:
YARN_CACHE_FOLDER: $(Pipeline.Workspace)/.yarn
steps:
- task: Cache@2
inputs:
key: '"yarn" | "$(Agent.OS)" | yarn.lock'
restoreKeys: |
yarn | "$(Agent.OS)"
yarn
path: $(YARN_CACHE_FOLDER)
displayName: Cache Yarn packages
- script: yarn --frozen-lockfile
在此範例中,快取工作會嘗試尋找索引鍵是否存在於快取中。 如果金鑰不存在於快取中,它會嘗試使用第一個還原密鑰 yarn | $(Agent.OS)
。
這會嘗試搜尋完全符合該索引鍵或將該索引鍵作為前綴的任何索引鍵。 如果有不同的 yarn.lock
哈希區段,可能會發生前綴碰撞。
例如,如果下列索引鍵 yarn | $(Agent.OS) | old-yarn.lock
位於快取中,而 old-yarn.lock
產生與 yarn.lock
不同的哈希值,則還原索引鍵會產生部分命中。
如果第一個還原密鑰失敗,則會使用下一個還原密鑰 yarn
,這會嘗試尋找任何以 yarn
開頭的密鑰。 在前綴命中的情況下,結果會產生最近建立的快取索引鍵。
注意
資料流可以有一個或多個快取任務。 快取記憶體容量沒有上限,來自相同管線的作業和任務可以存取和共用相同的快取。
快取隔離和安全性
為了確保不同管線和不同分支之間的快取隔離性,每個快取都屬於一個稱為「作用域」的邏輯容器。 範圍提供安全性界限,可確保:
- 來自一個管線的任務無法存取來自不同管線的快取,而且
- 建置 PR 的作業具有 PR 目標分支快取的讀取許可權(針對相同的管線),但無法在目標分支的範圍內寫入(建立)快取。
在執行過程中遇到快取步驟時,會向伺服器請求由鍵值識別的快取。 然後,伺服器會從作業可見的範圍中尋找具有此索引鍵的快取,並返回快取(如果可用的話)。 在快取儲存時(在作業結束時),快取會寫入代表管線和分支的範圍。 如需詳細資訊,請參閱下方。
CI、手動和排程的執行
範圍 | 閱讀 | 寫 |
---|---|---|
來源分支 | 是的 | 是的 |
main 分支 |
是的 | 不 |
master 分支 |
是的 | 不 |
拉取請求執行
範圍 | 讀 | 寫 |
---|---|---|
來源分支 | 是的 | 不 |
目標分支 | 是的 | 不 |
中繼分支(例如 refs/pull/1/merge ) |
是的 | 是的 |
main 分支 |
是的 | 不 |
master 分支 |
是的 | 不 |
拉取請求分支運行
分支 | 閱讀 | 寫 |
---|---|---|
目標分支 | 是的 | 不 |
中繼分支(例如 refs/pull/1/merge ) |
是的 | 是的 |
main 分支 |
是的 | 不 |
master 分支 |
是的 | 不 |
提示
由於快取已限定於專案、管線和分支,因此不需要在快取索引鍵中包含任何專案、管線或分支標識符。
快取條件設定
在某些情況下,快取的成功還原應該會導致執行一組不同的步驟。 例如,如果快取已還原,可以略過安裝相依項目的步驟。 這可以透過使用 cacheHitVar
任務輸入來實現。 將此輸入設定為環境變數的名稱,會在發生快取叫用時將變數設定為 true
,inexact
在還原金鑰快取叫用時,否則會設定為 false
。 然後,您可以在 步驟條件 或腳本內參考此變數。
在下列範例中,還原快取時會略過 install-deps.sh
步驟:
steps:
- task: Cache@2
inputs:
key: mykey | mylockfile
restoreKeys: mykey
path: $(Pipeline.Workspace)/mycache
cacheHitVar: CACHE_RESTORED
- script: install-deps.sh
condition: ne(variables.CACHE_RESTORED, 'true')
- script: build.sh
Bundler(封包管理工具)
針對使用 Bundler 的 Ruby 專案,請覆寫 Bundler 用來設定 路徑 Bundler 尋找 Gems 的 BUNDLE_PATH
環境變數。
範例:
variables:
BUNDLE_PATH: $(Pipeline.Workspace)/.bundle
steps:
- task: Cache@2
displayName: Bundler caching
inputs:
key: 'gems | "$(Agent.OS)" | Gemfile.lock'
path: $(BUNDLE_PATH)
restoreKeys: |
gems | "$(Agent.OS)"
gems
Ccache (C/C++)
Ccache 是 C/C++ 的編譯器快取。 若要在管線中使用 Ccache,請確定已安裝 Ccache
,並選擇性地將其新增至 PATH
(詳見 ,Ccache 的執行模式)。 將 CCACHE_DIR
環境變數設定為 $(Pipeline.Workspace)
下的路徑,並快取此目錄。
範例:
variables:
CCACHE_DIR: $(Pipeline.Workspace)/ccache
steps:
- bash: |
sudo apt-get install ccache -y
echo "##vso[task.prependpath]/usr/lib/ccache"
displayName: Install ccache and update PATH to use linked versions of gcc, cc, etc
- task: Cache@2
displayName: Ccache caching
inputs:
key: 'ccache | "$(Agent.OS)" | $(Build.SourceVersion)'
path: $(CCACHE_DIR)
restoreKeys: |
ccache | "$(Agent.OS)"
如需詳細資訊,請參閱 Ccache 組態設定。
Docker 映像檔
快取 Docker 映像可大幅減少執行管線所需的時間。
variables:
repository: 'myDockerImage'
dockerfilePath: '$(Build.SourcesDirectory)/app/Dockerfile'
tag: '$(Build.BuildId)'
pool:
vmImage: 'ubuntu-latest'
steps:
- task: Cache@2
displayName: Cache task
inputs:
key: 'docker | "$(Agent.OS)" | cache'
path: $(Pipeline.Workspace)/docker
cacheHitVar: CACHE_RESTORED #Variable to set to 'true' when the cache is restored
- script: |
docker load -i $(Pipeline.Workspace)/docker/cache.tar
displayName: Docker restore
condition: and(not(canceled()), eq(variables.CACHE_RESTORED, 'true'))
- task: Docker@2
displayName: 'Build Docker'
inputs:
command: 'build'
repository: '$(repository)'
dockerfile: '$(dockerfilePath)'
tags: |
'$(tag)'
- script: |
mkdir -p $(Pipeline.Workspace)/docker
docker save -o $(Pipeline.Workspace)/docker/cache.tar $(repository):$(tag)
displayName: Docker save
condition: and(not(canceled()), not(failed()), ne(variables.CACHE_RESTORED, 'true'))
- 鍵:(必要)- 快取唯一識別符。
- 路徑: (必要) - 您要快取的資料夾或檔案路徑。
Golang
針對 Golang 專案,您可以指定要在 go.mod 檔案中下載的套件。 如果您的 GOCACHE
變數尚未設定,請將它設定為您想要下載快取的位置。
範例:
variables:
GO_CACHE_DIR: $(Pipeline.Workspace)/.cache/go-build/
steps:
- task: Cache@2
inputs:
key: 'go | "$(Agent.OS)" | go.mod'
restoreKeys: |
go | "$(Agent.OS)"
path: $(GO_CACHE_DIR)
displayName: Cache GO packages
Gradle
使用 Gradle 的 內建快取支援 可能會對建置時間產生重大影響。 若要啟用組建快取,請將 GRADLE_USER_HOME
環境變數設定為 $(Pipeline.Workspace)
下的路徑,並使用 --build-cache
執行您的組建,或將 org.gradle.caching=true
新增至您的 gradle.properties
檔案。
範例:
variables:
GRADLE_USER_HOME: $(Pipeline.Workspace)/.gradle
steps:
- task: Cache@2
inputs:
key: 'gradle | "$(Agent.OS)" | **/build.gradle.kts' # Swap build.gradle.kts for build.gradle when using Groovy
restoreKeys: |
gradle | "$(Agent.OS)"
gradle
path: $(GRADLE_USER_HOME)
displayName: Configure gradle caching
- task: Gradle@2
inputs:
gradleWrapperFile: 'gradlew'
tasks: 'build'
options: '--build-cache'
displayName: Build
- script: |
# stop the Gradle daemon to ensure no files are left open (impacting the save cache operation later)
./gradlew --stop
displayName: Gradlew stop
- restoreKeys:主鍵失敗時後援密鑰 (選擇性)
注意
快取是不可變的,一旦針對特定範圍 (分支) 建立具有特定索引鍵的快取之後,就無法更新快取。 這表示如果索引鍵是固定值,即使快取的內容已變更,相同分支的所有後續組建都將無法更新快取。 如果您想要使用固定索引鍵值,則必須使用 restoreKeys
自變數做為後援選項。
Maven
Maven 具有本地儲存庫,用於儲存下載和建置成品。 若要啟用,請將 [maven.repo.local
] 選項設定為 $(Pipeline.Workspace)
下的路徑,並快取此資料夾。
範例:
variables:
MAVEN_CACHE_FOLDER: $(Pipeline.Workspace)/.m2/repository
MAVEN_OPTS: '-Dmaven.repo.local=$(MAVEN_CACHE_FOLDER)'
steps:
- task: Cache@2
inputs:
key: 'maven | "$(Agent.OS)" | **/pom.xml'
restoreKeys: |
maven | "$(Agent.OS)"
maven
path: $(MAVEN_CACHE_FOLDER)
displayName: Cache Maven local repo
- script: mvn install -B -e
如果您正在使用 Maven 任務,請務必傳遞 MAVEN_OPTS
變數,否則它會被覆寫:
- task: Maven@4
inputs:
mavenPomFile: 'pom.xml'
mavenOptions: '-Xmx3072m $(MAVEN_OPTS)'
.NET/NuGet
如果您在專案檔中直接使用 PackageReferences
來管理 NuGet 相依性,並擁有 packages.lock.json
檔案,您可以透過將 NUGET_PACKAGES
環境變數設定為 $(UserProfile)
下的某個路徑,並快取該目錄來啟用快取。 如需如何鎖定相依性的詳細資訊,請參閱項目檔中的 套件參考。
如果您想要使用多個 packages.lock.json,您仍然可以使用下列範例而不進行任何變更。 所有 packages.lock.json 檔案的內容都會經過哈希處理,如果其中一個檔案已變更,就會產生新的快取索引鍵。
範例:
variables:
NUGET_PACKAGES: $(Pipeline.Workspace)/.nuget/packages
steps:
- task: Cache@2
inputs:
key: 'nuget | "$(Agent.OS)" | $(Build.SourcesDirectory)/**/packages.lock.json'
restoreKeys: |
nuget | "$(Agent.OS)"
nuget
path: $(NUGET_PACKAGES)
displayName: Cache NuGet packages
如果您的專案使用 packages.lock.json 鎖定套件版本,此方法也適用於 .NET Core 專案。 您可以將 RestorePackagesWithLockFile
設定為 Csproj 檔案中的 True
,或使用下列命令來啟用此功能:dotnet restore --use-lock-file
。
Node.js/npm
在 Node.js 項目中啟用快取的方式有不同,但建議的方式是快取 npm 的 共用快取目錄。 此目錄由 npm 管理,並包含所有已下載模組的快取版本。 在安裝期間,npm 會優先檢查此目錄,以尋找可以減少或排除對公用 npm 註冊表或私人註冊表進行網路呼叫的模組。
由於 npm 共用快取目錄的預設路徑 在所有平臺上不同,因此建議將 npm_config_cache
環境變數覆寫至 $(Pipeline.Workspace)
下的路徑。 這同時確保了快取可以從容器和非容器作業中被存取。
範例:
variables:
npm_config_cache: $(Pipeline.Workspace)/.npm
steps:
- task: Cache@2
inputs:
key: 'npm | "$(Agent.OS)" | package-lock.json'
restoreKeys: |
npm | "$(Agent.OS)"
path: $(npm_config_cache)
displayName: Cache npm
- script: npm ci
如果您的項目沒有 package-lock.json
檔案,請改為參考快取索引鍵輸入中的 package.json
檔案。
提示
由於 npm ci
會刪除 node_modules
資料夾,以確保使用一致的可重複模組集,因此您應該避免在呼叫 npm ci
時快取 node_modules
。
Node.js/Yarn
和 npm 一樣,有不同的方式來快取隨 Yarn 安裝的套件。 建議的方式是將 Yarn 的共用快取資料夾 快取到。 此目錄由 Yarn 管理,並包含所有下載套件的快取版本。 在安裝期間,Yarn 會先檢查此目錄是否有模組,這樣可減少或排除對公用或私人登錄的網路呼叫。
範例:
variables:
YARN_CACHE_FOLDER: $(Pipeline.Workspace)/.yarn
steps:
- task: Cache@2
inputs:
key: 'yarn | "$(Agent.OS)" | yarn.lock'
restoreKeys: |
yarn | "$(Agent.OS)"
yarn
path: $(YARN_CACHE_FOLDER)
displayName: Cache Yarn packages
- script: yarn --frozen-lockfile
Python/Anaconda
利用 Anaconda 環境來設定您的管線快取:
例
variables:
CONDA_CACHE_DIR: /usr/share/miniconda/envs
# Add conda to system path
steps:
- script: echo "##vso[task.prependpath]$CONDA/bin"
displayName: Add conda to PATH
- bash: |
sudo chown -R $(whoami):$(id -ng) $(CONDA_CACHE_DIR)
displayName: Fix CONDA_CACHE_DIR directory permissions
- task: Cache@2
displayName: Use cached Anaconda environment
inputs:
key: 'conda | "$(Agent.OS)" | environment.yml'
restoreKeys: |
python | "$(Agent.OS)"
python
path: $(CONDA_CACHE_DIR)
cacheHitVar: CONDA_CACHE_RESTORED
- script: conda env create --quiet --file environment.yml
displayName: Create Anaconda environment
condition: eq(variables.CONDA_CACHE_RESTORED, 'false')
Windows
- task: Cache@2 displayName: Cache Anaconda inputs: key: 'conda | "$(Agent.OS)" | environment.yml' restoreKeys: | python | "$(Agent.OS)" python path: $(CONDA)/envs cacheHitVar: CONDA_CACHE_RESTORED - script: conda env create --quiet --file environment.yml displayName: Create environment condition: eq(variables.CONDA_CACHE_RESTORED, 'false')
PHP/Composer
對於使用 Composer 的 PHP 專案,請覆寫 Composer 所使用的 COMPOSER_CACHE_DIR
環境變數。
範例:
variables:
COMPOSER_CACHE_DIR: $(Pipeline.Workspace)/.composer
steps:
- task: Cache@2
inputs:
key: 'composer | "$(Agent.OS)" | composer.lock'
restoreKeys: |
composer | "$(Agent.OS)"
composer
path: $(COMPOSER_CACHE_DIR)
displayName: Cache composer
- script: composer install
已知問題和意見反應
如果您在設定管線快取時遇到問題,請檢查在 microsoft/azure-pipelines-tasks 存放庫中 開啟的 問題清單。 如果您沒有看到列出的問題,建立 新的問題,並提供案例的必要資訊。
Q&A
問:我可以清除快取嗎?
目前不支援清除快取。 然而,您可以將字串常值(例如 version2
)新增到現有的快取索引鍵中,以變更該索引鍵,從而避免現有快取受到任何請求命中。 例如,將下列快取金鑰變更為:
key: 'yarn | "$(Agent.OS)" | yarn.lock'
對此:
key: 'version2 | yarn | "$(Agent.OS)" | yarn.lock'
問:快取何時到期?
答:快取會在七天沒有活動後失效。
問:快取何時上傳?
答:在管線的最後一個步驟之後,將會從快取 path
建立快取並上傳。 如需詳細資訊,請參閱 範例。
快取的大小是否有限制?
答:沒有個別快取大小或組織中所有快取大小總計的強制限制。