Table of Contents

Push an image to a remote repository

using OrasProject.Oras.Registry.Remote;
using OrasProject.Oras.Registry;
using OrasProject.Oras.Oci;
using OrasProject.Oras.Registry.Remote.Auth;
using Microsoft.Extensions.Caching.Memory;

namespace OrasProject.Oras.Tests.Examples;

public static class PushImage
{
    // This example demonstrates how to push an image to a remote repository.
    // For production use: Implement proper exception handling, cancellation, and dependency injection.
    public static async Task PushImageAsync()
    {
        const string registry = "localhost:5000"; // change to your target registry
        const string repository = "myrepo/test"; // change to your target repository

        // Create a HttpClient instance for making HTTP requests.
        var httpClient = new HttpClient();

        // Create a simple credential provider with static credentials.
        var credentialProvider = new SingleRegistryCredentialProvider(registry, new Credential
        {
            RefreshToken = "refresh_token" // change to your actual refresh token
        });

        // Create a memory cache for caching access tokens to improve auth performance.
        var memoryCache = new MemoryCache(new MemoryCacheOptions());

        // Create a repository instance to interact with the target repository.
        var repo = new Repository(new RepositoryOptions
        {
            Reference = Reference.Parse($"{registry}/{repository}"),
            Client = new Client(httpClient, credentialProvider, new Cache(memoryCache)),
        });

        // Push config and layers to the repository.
        var configBytes = new byte[] { 0x01, 0x02, 0x03 }; // Example config bytes.
        var config = Descriptor.Create(configBytes, MediaType.ImageConfig);

        var layerBytesList = new List<byte[]>
        {
            new byte[] { 0x04, 0x05, 0x06 }, // example layer data
            new byte[] { 0x07, 0x08, 0x09 } // another example layer data
        };
        var layers = new List<Descriptor>
        {
            Descriptor.Create(layerBytesList[0], MediaType.ImageLayer),
            Descriptor.Create(layerBytesList[1], MediaType.ImageLayer)
        };
        await repo.PushAsync(config, new MemoryStream(configBytes));
        for (int i = 0; i < layers.Count; i++)
        {
            await repo.PushAsync(layers[i], new MemoryStream(layerBytesList[i]));
        }

        // Pack a manifest for the artifact and push it to the repository.
        var options = new PackManifestOptions
        {
            Config = config,
            Layers = layers
        };
        var manifestDescriptor = await Packer.PackManifestAsync(repo, Packer.ManifestVersion.Version1_1, "", options);

        // Tag the pushed manifest so it can be referenced by a human-readable name.
        const string tag = "tag"; // choose a tag for your image
        await repo.TagAsync(manifestDescriptor, tag);
    }
}