ActionsToolkit.Cache 1.0.0

dotnet add package ActionsToolkit.Cache --version 1.0.0
                    
NuGet\Install-Package ActionsToolkit.Cache -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ActionsToolkit.Cache" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ActionsToolkit.Cache" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="ActionsToolkit.Cache" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ActionsToolkit.Cache --version 1.0.0
                    
#r "nuget: ActionsToolkit.Cache, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ActionsToolkit.Cache@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ActionsToolkit.Cache&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=ActionsToolkit.Cache&version=1.0.0
                    
Install as a Cake Tool

ActionsToolkit.Cache

NuGet

An unofficial .NET SDK for GitHub Actions workflows, providing a port of the @actions/cache JavaScript package. Use it from a custom action (or a workflow-driven .NET process running on a GitHub Actions runner) to save a list of files / directories under a key and restore them on a later run.

Install

<PackageReference Include="ActionsToolkit.Cache" Version="[Version]" />

Or use the dotnet add package .NET CLI command:

dotnet add package ActionsToolkit.Cache

Get the ICacheClient instance

Register the services with an IServiceCollection instance by calling AddCacheServices(), and consuming code can require the ICacheClient via constructor dependency injection.

using ActionsToolkit.Cache;
using ActionsToolkit.Cache.Services;
using Microsoft.Extensions.DependencyInjection;

using var provider = new ServiceCollection()
    .AddCacheServices()
    .BuildServiceProvider();

var cache = provider.GetRequiredService<ICacheClient>();

AddCacheServices() reads ACTIONS_RESULTS_URL and ACTIONS_RUNTIME_TOKEN (set automatically by the runner) at the time each HttpClient is materialized; you don't need to configure them explicitly. Call cache.IsFeatureAvailable() if you want to short-circuit gracefully when the env vars are absent.

Save a cache

var entry = await cache.SaveCacheAsync(
    paths: ["bin", "obj"],
    key: $"build-{Environment.OSVersion.Platform}-{commitSha}");

if (entry is not null)
{
    Console.WriteLine($"Saved cache {entry.Key} ({entry.Size} bytes)");
}

The client tar+zstd-compresses the listed paths, reserves a cache entry via the V2 Twirp CreateCacheEntry RPC, PUTs the archive to the signed upload URL, and finalizes the entry with FinalizeCacheEntryUpload. Compression uses the ZstdSharp.Port AOT-clean managed zstd implementation — there is no dependency on a native zstd binary, tar binary, or the Azure Storage Blobs SDK.

Restore a cache

string? matchedKey = await cache.RestoreCacheAsync(
    paths: ["bin", "obj"],
    primaryKey: $"build-{Environment.OSVersion.Platform}-{commitSha}",
    restoreKeys: [$"build-{Environment.OSVersion.Platform}-"]);

if (matchedKey is not null)
{
    Console.WriteLine($"Cache hit: {matchedKey}");
}

restoreKeys are searched in order after the primary key misses; the first prefix-match wins. The matched key is returned (which may equal primaryKey for an exact hit, or one of the restore keys for a fallback hit). On miss, null is returned.

Lookup-only

var key = await cache.RestoreCacheAsync(
    paths,
    primaryKey,
    restoreKeys,
    options: new RestoreCacheOptions { LookupOnly = true });

When LookupOnly = true, the client checks whether a matching entry exists and returns the matched key without downloading or extracting the archive — useful in jobs that only need to know whether a follow-up step should rebuild.

Cross-OS archives

By default, a cache saved on Windows can only be restored on Windows (the OS marker is mixed into the version hash). Set enableCrossOsArchive: true on both SaveCacheAsync and RestoreCacheAsync to produce a portable archive.

Key & path validation

Rule Source
At least one path CacheValidationException
Key ≤ 512 chars CacheValidationException
Key contains no commas CacheValidationException
≤ 10 keys total (primary + restore) CacheValidationException

Errors

Exception Thrown when
CacheValidationException A key or path violates the input rules above.
ReserveCacheException CreateCacheEntry returned ok=false (another job may already own the key).
FinalizeCacheException FinalizeCacheEntryUpload returned ok=false after the blob upload.
CacheServiceUnavailableException ACTIONS_RESULTS_URL (V2) / ACTIONS_CACHE_URL (V1) is unset.
CacheServiceException The Twirp service or signed-URL transport returned an unexpected status / payload.

Environment

Variable Purpose
ACTIONS_RESULTS_URL Base URL of the V2 cache service (set by the runner).
ACTIONS_RUNTIME_TOKEN Bearer token used for Twirp calls.
ACTIONS_CACHE_SERVICE_V2 When set, opt in to the V2 service (default on hosted runners).
GITHUB_WORKSPACE Root used to resolve relative paths during tar create / extract.
RUNNER_TEMP Optional override for the temp folder used to stage archives.

Architecture

The package decomposes the cache flows into injectable seams:

  • ICacheClient — the public façade. The DI default (DefaultCacheClient) routes save through CreateCacheEntry → signed-URL PUTFinalizeCacheEntryUpload, and restore through GetCacheEntryDownloadURL → signed-URL GET → tar extract.
  • ICacheTwirpService (internal) — Twirp transport. Issues POST /twirp/github.actions.results.api.v1.CacheService/<Method> requests with the runtime token bearer.
  • CacheTar (internal) — tar+zstd archive create / extract using System.Formats.Tar (built-in) and ZstdSharp.Port (managed zstd).

The package registers two named HttpClient instances:

Name Purpose
ActionsToolkit.Cache Twirp transport (bearer auth from ACTIONS_RUNTIME_TOKEN).
ActionsToolkit.Cache.Blob Bare client for blob upload/download via signed URLs (no auth).

Native AOT

The package is fully Native AOT-clean. JSON serialization uses a [JsonSerializable] source-gen context (CacheJsonContext); zstd compression uses managed code (ZstdSharp.Port); tar uses the built-in System.Formats.Tar API. There is no reflection, no JsonSerializer overload that takes a Type, and no Microsoft.IdentityModel.* dependency.

Attribution

Based on the original Node.js @actions/cache package by GitHub, licensed under Apache-2.0. The .NET port is MIT-licensed and is not an official GitHub product.

Compression is handled by the ZstdSharp.Port managed zstd library; tar archive support is provided by the built-in System.Formats.Tar API in .NET 10.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 81 5/5/2026
1.0.0-rc.1 52 5/5/2026