管線快取

Azure DevOps Services

管線快取可藉由允許輸出或下載的相依性在稍後的執行中重複使用,藉此減少或避免重新建立或重新下載相同檔案的成本,藉此減少建置時間。 在每次執行開始時下載相同相依性的案例中,快取特別有用。 這通常是一個耗時的程式,涉及數百或數千個網路呼叫。

快取可以在改善建置時間時生效,前提是還原和儲存快取的時間小於從頭開始產生輸出的時間。 因此,快取在所有案例中可能都無效,而且實際上可能會對建置時間產生負面影響。

CI 和部署作業目前支援快取,但不支援傳統發行作業。

使用成品與快取的時機

管線快取和 管線成品 會執行類似的函式,但專為不同的案例而設計,不應交替使用。

  • 當您需要擷取一個作業中產生的特定檔案,並與其他作業共用它們時,請使用管線成品 (而且這些其他作業可能會失敗,而不會失敗)。

  • 當您想要藉由重複使用先前執行的檔案來改善建置時間時,請使用管線快 取(而沒有這些檔案不會影響作業的執行能力)。

注意

管線快取和管線成品適用於所有層(免費和付費)。 如需詳細資訊,請參閱 成品記憶體耗用量

快取工作:其運作方式

快取會使用 快取工作新增至管線。 此工作的運作方式就像任何其他工作一樣,而且會新增至 steps 作業的 區段。

在執行期間遇到快取步驟時,工作會根據提供的輸入還原快取。 如果找不到快取,步驟就會完成,而作業中的下一個步驟會執行。

在作業中的所有步驟都已執行並假設作業狀態成功之後,系統會自動新增並觸發每個未略過之「還原快取」步驟的特殊「作業後:快取」步驟。 此步驟負責 儲存快取

注意

快取是不可變的,這表示一旦建立快取,就無法變更其內容。

設定快取工作

取工作 有兩個必要自變數: 索引鍵路徑

  • path:要快取的資料夾路徑。 可以是絕對路徑或相對路徑。 相對路徑會針對 $(System.DefaultWorkingDirectory)解析。

注意

您可以使用 預先定義的變數 來儲存您要快取之資料夾的路徑,不過不支援通配符。

  • key:應該設定為您要還原或儲存之快取的標識碼。 索引鍵是由字串值、檔案路徑或檔案模式的組合所組成,其中每個區段會以 | 字元分隔。
  • 字串:
    固定值(例如快取的名稱或工具名稱)或取自環境變數(例如目前的 OS 或目前的作業名稱)

  • 檔案路徑
    將哈希內容的特定檔案路徑。 此檔案必須在工作執行時存在。 請記住, 任何 「看起來像檔案路徑」的主要區段都會被視為檔案路徑。 特別是,這包括包含的 .區段。 當這個「檔案」不存在時,這可能會導致工作失敗。

    提示

    若要避免將類似路徑的字串區段視為檔案路徑,請使用雙引號來包裝它,例如: "my.key" | $(Agent.OS) | key.file

  • 檔案模式
    Glob 樣式通配符模式的逗號分隔清單,必須符合至少一個檔案。 例如:

    • **/yarn.lock:sources 目錄下的所有 yarn.lock 檔案
    • */asset.json, !bin/**:所有asset.json位於來源目錄下目錄目錄的檔案,但 bin 目錄底下除外

檔案路徑或檔案模式所識別之任何檔案的內容會哈希以產生動態快取索引鍵。 當您的專案有可唯一識別快取專案的檔案時,這會很有用。 例如,、、 Gemfile.lockPipfile.lockyarn.lockpackage-lock.json檔案通常會在快取索引鍵中參考,因為它們全都代表唯一的相依性集。

相對檔案路徑或檔案模式會針對 $(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 如果要針對多個精確索引鍵或索引鍵前置詞進行查詢,則可以使用 。 這可用來回復至另一個索引鍵,以防 a key 不會產生命中。 還原金鑰會依前置詞搜尋密鑰,並因此產生最新的建立快取專案。 如果管線找不到完全相符專案,但想要改用部分快取叫用,這非常有用。 若要插入多個還原密鑰,只要使用新行來指出還原密鑰來分隔它們(如需詳細資訊,請參閱範例)。 將嘗試還原金鑰的順序會從上到下。

自我裝載代理程式上的必要軟體

封存軟體/ 平臺 Windows Linux Mac
GNU Tar 必要 必要 No
BSD Tar No 必要
7-Zip 建議需求 No No

上述可執行文件必須位於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、手動和排程的執行

範圍 讀取 寫入
來源分支 Yes Yes
main 分支 (預設分支) No

提取要求執行

範圍 讀取 寫入
來源分支 No
目標分支 No
中繼分支 (例如 refs/pull/1/merge Yes Yes
main 分支 (預設分支) No

提取要求分支執行

分支 讀取 寫入
目標分支 No
中繼分支 (例如 refs/pull/1/merge Yes Yes
main 分支 (預設分支) No

提示

由於快取已限定於專案、管線和分支,因此不需要在快取索引鍵中包含任何專案、管線或分支標識符。

快取還原的調理

在某些情況下,快取的成功還原應該會導致執行一組不同的步驟。 例如,如果還原快取,可以略過安裝相依性的步驟。 這可以使用工作 cacheHitVar 輸入。 將此輸入設定為環境變數的名稱會導致變數在發生快取叫用時設定為 trueinexact 否則它會設定為 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 專案,請覆寫 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 是 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'))
  • key:(必要) - 快取的唯一標識符。
  • path: (必要) - 您要快取的資料夾或檔案路徑。

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)的路徑,並使用 或 新增org.gradle.caching=true至檔案來執行您的gradle.properties組建--build-cache

範例:

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

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_CACHE_DIRComposer 所使用的環境變數

範例:

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 並上傳。 如需詳細資訊, 請參閱範例

問:快取的大小是否有限制?

答:沒有個別快取大小或組織中所有快取大小總計的強制限制。