How to create a GitHub Repository Picker using Octokit and Contentment

Posted written by Paul Seal on October 24, 2023 C# Umbraco

This week I did the Umbraco Cloud training course. In that course, one of the excercises was to use the Octokit NuGet package to be able to render a list of GitHub repositories on the page.

I thought it would be a good idea to create a Data List Source for Contentment using this Octokit package, so this post is just for me to share the code I wrote to get it working.

First Install Octokit into your project

dotnet add package Octokit

Install the Octokit package via NuGet

Next, add a helper class to your project

using Octokit;
namespace UmbracoProject.Helpers;

public class GithubHelper
{
    public static IReadOnlyList<Repository> GetRepositories(string productHeader, string username)
    {
        var client = new GitHubClient(new Octokit.ProductHeaderValue(productHeader));
        return client.Repository.GetAllForUser(username).Result;
    }
}

Add a helper class to your project

Create a custom Contentment Data List Source

using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Community.Contentment.DataEditors;

using UmbracoProject.Helpers;

namespace UmbracoProject.Contentment.DataSources;

public class GitHubRepositoryDataListSource : IDataListSource
{
    public string Name => "GitHub Repositories";

    public string Description => "Use GitHub repositories as a data source.";

    public string Icon => "icon-github";

    public OverlaySize OverlaySize => OverlaySize.Small;

    public Dictionary<string, object> DefaultValues => new Dictionary<string, object>();

    public IEnumerable<ConfigurationField> Fields => new ConfigurationField[]
    {
        new ConfigurationField
        {
            Key = "productHeaderValue",
            Name = "Product Header Value",
            Description = "Set the product header value which gets passed to the GitHub API. This is also to identify applications that are accessing the API and enable GitHub to contact the application author if there are problems. So pick a name that stands out!",
            View =  "textstring",
        },
        new ConfigurationField
        {
            Key = "username",
            Name = "Username",
            Description = "Set the GitHub username to pull the repositories from.",
            View =  "textstring",
        },
    };

    public string Group => "Custom";

    public IEnumerable<DataListItem> GetItems(Dictionary<string, object> config)
    {
        if (!config.TryGetValue("username", out var username)) return Enumerable.Empty<DataListItem>();

        if (username == null || string.IsNullOrWhiteSpace(username.ToString())) return Enumerable.Empty<DataListItem>();

        if (!config.TryGetValue("productHeaderValue", out var productHeaderValue)) return Enumerable.Empty<DataListItem>();

        if (productHeaderValue == null || string.IsNullOrWhiteSpace(productHeaderValue.ToString())) return Enumerable.Empty<DataListItem>();

        var repos = GithubHelper.GetRepositories(productHeaderValue.ToString(), username.ToString());

        List<DataListItem> results = new List<DataListItem>();

        //make sure there are some repo items
        if (repos != null && repos.Any())
        {

            repos = repos.Where(x => !x.Fork).OrderByDescending(x => x.StargazersCount).ThenBy(x => x.ForksCount).ToList();
            //loop through the repo itmes
            foreach (var repo in repos)
            {
                //create a new DataListItem object to store the data
                var item = new DataListItem()
                {
                    Name = $"{repo.Name} (Stars:{repo.StargazersCount}, Forks:{repo.ForksCount})",
                    Value = repo.Id.ToString()
                };

                //add the item to our list of results
                results.Add(item);
            }

            return results;
        }

        return Enumerable.Empty<DataListItem>();
    }

}

Create a custom Contentment Data List Source

That should be it. Now you can use it to create your data type.

1

How the GitHub Repository Picker Looks

2

The configuration options for the data source