Azure DevOps Services
管道快取能夠透過重複使用之前執行過的下載相依性,協助縮短建置時間,避免不得不重新建立或下載相同的檔案。 這在每次執行開始時重複下載相同相依性的情況特別有用。 這通常是一個耗時的過程,涉及數百或數千個網路呼叫。
當還原和儲存快取所需的時間小於重新產生檔案所需的時間時,快取最有效。 不過,在某些情況下,快取可能無法提供效能優勢,甚至可能會對建置時間造成負面影響。 務必評估您的特定情境,以判斷快取是否是正確的做法。
何時使用管線產物與管線快取
管線快取和管線成品執行類似功能,但用途不同,不應互換使用。
自行託管的代理程式需求
下列可執行文件必須位於環境變數中列出的 PATH 資料夾中。 請注意,這些需求僅適用於自我裝載的代理程式,因為裝載的代理程式會預安裝必要的軟體。
| 封存軟體/ 平臺 |
窗戶 |
Linux |
Mac(蘋果電腦) |
| GNU Tar |
必填 |
必填 |
不 |
| BSD 焦油 |
不 |
不 |
必填 |
| 7 拉鍊 |
推薦 |
不 |
不 |
快取工作:運作方式
將 快取工作 加入至 steps 作業的區段,便可將快取新增至管線。
在管線執行期間,當遇到快取步驟時,任務會嘗試根據提供的輸入復原快取。 如果找不到任何快取,步驟就會完成,並執行作業中的下一個步驟。
一旦作業中的所有步驟都順利執行,系統會自動新增並觸發每個未略過的「還原快取」步驟,並加入一個特殊的「作業後:快取」步驟。 此步驟負責 儲存快取。
注意
快取是不可變的。 建立快取之後,就無法修改其內容。
快取任務有兩個必要參數:路徑和索引鍵。
path:要快取的資料夾路徑。 這可以是絕對路徑或相對路徑。 相對路徑是相對於 $(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 沒有命中時,它會被用作備援措施。 復原鍵會依前綴搜尋金鑰,並傳回最近建立的快取項目。 當管線找不到完全相符的項目,但仍想要使用部分快取命中時,這會很有幫助。
若要指定多個還原金鑰,請將它們列在不同的行上。 嘗試還原金鑰的順序是從上到下。
以下是如何使用還原金鑰來快取 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 | $(Agent.OS) | old-yarn.lock(其中 old-yarn.lock 的哈希值與目前的 yarn.lock 不同),這個還原鍵將導致部分快取命中。
如果第一個還原金鑰沒有匹配結果,則使用下一個還原金鑰 (yarn)。這會搜尋所有以 yarn 開頭的快取金鑰。 針對前綴匹配,還原過程會傳回最近建立的快取項目。
注意
管道可以包含多個快取工作,且快取沒有儲存限制。 相同管線內的作業和任務可以存取和共用相同的快取。
使用還原條件
在某些情況下,您可能會想要根據快取是否成功還原,有條件地執行步驟。 例如,如果已還原快取,您可以略過安裝相依性的步驟。 這可以使用 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
快取隔離和安全性
為了確保不同管線和不同分支之間的快取隔離,每個快取都會儲存在一個稱為 範圍 的邏輯容器內。 範圍作為安全邊界來保證:
在執行過程中遇到快取步驟時,會向伺服器請求由鍵值識別的快取。 然後,伺服器會從作業可見的範圍中尋找具有此索引鍵的快取,並返回快取(如果可用的話)。 在快取儲存時(在作業結束時),快取會寫入代表管線和分支的範圍。
持續整合(CI)、手動和排程的運行
| 範圍 |
閱讀 |
寫 |
| 來源分支 |
是的 |
是的 |
main 分支 |
是的 |
不 |
master 分支 |
是的 |
不 |
拉取請求執行
| 範圍 |
閱讀 |
寫 |
| 來源分支 |
是的 |
不 |
| 目標分支 |
是的 |
不 |
中繼分支(例如 refs/pull/1/merge) |
是的 |
是的 |
main 分支 |
是的 |
不 |
master 分支 |
是的 |
不 |
拉取請求分支運行
| 分支 |
閱讀 |
寫 |
| 目標分支 |
是的 |
不 |
中繼分支(例如 refs/pull/1/merge) |
是的 |
是的 |
main 分支 |
是的 |
不 |
master 分支 |
是的 |
不 |
提示
由於快取已限定於專案、管線和分支,因此不需要在快取索引鍵中包含任何專案、管線或分支標識符。
範例
對於使用 Bundler 的 Ruby 專案,請覆寫 BUNDLE_PATH 環境變數來設定 Bundler 尋找 Gem 的路徑。
範例:
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,請確定 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 映像檔可大幅減少運行您的管線所需的時間。
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' ## A unique identifier for the cache
path: $(Pipeline.Workspace)/docker ## Path of the folder or file that you want to cache
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'))
使用 docker buildx 的範例:
steps:
- task: Cache@2
displayName: Cache Docker
inputs:
key: 'docker | "$(Agent.OS)" | mydockerimage | ./Dockerfile'
path: $(Pipeline.Workspace)/docker_image_cache
restoreKeys: |
docker | "$(Agent.OS)" | mydockerimage
- script: |
docker buildx create --name builder --driver docker-container --use
docker buildx build \
--cache-from=type=local,src=$(Pipeline.Workspace)/docker_image_cache \
--cache-to=type=local,dest=$(Pipeline.Workspace)/docker_image_cache,mode=max \
--file ./Dockerfile \
--output=type=docker,name=mydockerimage \
.
displayName: docker buildx
env:
DOCKER_BUILDKIT: 1
針對 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_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: | # The fallback keys if the primary key fails (Optional)
gradle | "$(Agent.OS)"
gradle
path: $(GRADLE_USER_HOME)
displayName: Configure gradle caching
- task: Gradle@4 # Build using a Gradle wrapper script
inputs:
gradleWrapperFile: 'gradlew' # Alias: wrapperScript. Gradle wrapper.
tasks: 'build' # Default: build. Gradle tasks.
options: '--build-cache' # String. Gradle options.
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 輸入指定為後援選項。
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)'
如果您在專案檔中直接使用 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 設定為 True 檔案中的 ,或使用下列命令來啟用此功能:dotnet restore --use-lock-file。
在 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
如果您的項目沒有 package-lock.json 檔案,請改為參考快取索引鍵輸入中的 package.json 檔案。
提示
由於npm ci會刪除node_modules資料夾來確保模組集的一致性和可重複性,因此在使用node_modules時避免快取npm ci。
如同 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
利用 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')
對於使用 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清單。 如果您沒有看到列出的問題, 請建立 新的問題,並提供案例的必要資訊。
問答
問:我可以清除快取嗎?
答:不支援清除快取此功能。 不過,您可以將字串常值(例如 version2)新增至快取索引鍵,以避免命中現有的快取。 例如,將下列快取金鑰變更為:
key: 'yarn | "$(Agent.OS)" | yarn.lock'
對此:
key: 'version2 | yarn | "$(Agent.OS)" | yarn.lock'
問:快取何時到期?
答:快取會在七天沒有活動後失效。
問:快取何時上傳?
答:快取會從指定的 path 被建立,並在作業的最後一個步驟完成後上傳。 如需詳細資訊,請參閱 範例 。
快取的大小是否有限制?
答:組織內個別快取的大小或總快取大小沒有強制執行的限制。
相關內容