Ejemplo n.º 1
0
        public static async IAsyncEnumerable <(string repo, string label, string original)> MatchNodes(this HttpClient github, LabelEditedPayload payload)
        {
            var count = 0;
            var id    = payload.RepositoryId;
            var limit = payload.Limit;

            var oldName = payload.ChangedNameFrom;
            var newName = payload.LabelName;
            var search  = $"{newName} {oldName}";

            var privacy = payload.IgnorePrivate ? ", privacy: PUBLIC" : string.Empty;
            var suffix  = $", ownerAffiliations: OWNER{privacy}) {{ pageInfo {{ endCursor hasNextPage }} nodes {{ databaseId name labels(first: 10, query: \\\"{search}\\\") {{ nodes {{ name color description }} }} }} }} }} }}\"}}";
            var query   = $"{{\"query\":\"{{ viewer {{ repositories(first: {Math.Min(GitHubApi.MAX_ITEMS_PER_TRANSACTION, limit)}" + suffix;

            bool hasNextPage;
            var  promise = github.GraphQL(query);

            do
            {
                // Wait for results
                JObject data = await promise;

                var repos = data[DATA][VIEWER][REPOSITORIES];
                var page  = repos[PAGEINFO];
                hasNextPage = page[HASNEXTPAGE].Value <bool>();

                // If more data is available request it now
                if (hasNextPage)
                {
                    query   = $"{{\"query\":\"{{ viewer {{ repositories(first: {GitHubApi.MAX_ITEMS_PER_TRANSACTION}, after: \\\"{page["endCursor"].Value<string>()}\\\"" + suffix;
                    promise = github.GraphQL(query);
                }

                // Yield label info for each matching repository
                foreach (var node in repos[NODES])
                {
                    // Skip source repository
                    if (node[DATABASEID].Value <long>() == id)
                    {
                        continue;
                    }

                    // Scan and initialize found labels

                    JToken source = null;
                    JToken target = null;

                    foreach (var label in node[LABELS][NODES])
                    {
                        var name = label[NAME].Value <string>();
                        if (name == newName)
                        {
                            target = label;
                        }
                        if (name == oldName)
                        {
                            source = label;
                        }
                    }

                    var tuple =
                        (
                            repo : node[NAME].Value <string>(),
                            label : null as string,
                            original : null as string
                        );

                    // Assign found labels
                    if (null != source && null != target)
                    {
                        tuple.label    = target.Value <string>();
                        tuple.original = source[NAME].Value <string>();
                    }
                    else if (null != source)
                    {
                        tuple.label = source[NAME].Value <string>();
                    }
                    else if (null != target)
                    {
                        tuple.label = target[NAME].Value <string>();
                    }

                    yield return(tuple);

                    if (limit < ++count)
                    {
                        yield break;
                    }
                }
            }while (hasNextPage);
        }
Ejemplo n.º 2
0
        static async Task HandleLabelEditedEvent(this HttpClient github, LabelEditedPayload payload, ILogger log)
        {
            var count       = 0;
            var owner       = payload.OwnerLogin;
            var name        = payload.LabelName;
            var color       = payload.LabelColor;
            var changedName = payload.ChangedName;
            var description = payload.LabelDescription;

            log.LogInformation($"Updating label '{name}' in '{owner}' initiated by '{payload.SenderLogin}'");

            // When label is renamed, it requires checks for new and old
            // name so it is split in two possible cases here
            if (null != changedName && changedName.HasValues)
            {
                // Process changes in the name
                await foreach (var node in github.MatchNodes(payload))
                {
                    if (null != node.original)
                    {
                        // This is the case where both, the new label, and the old are present
                        // We need to delete one modify the other
                        var method = $"/repos/{owner}/{node.repo}/labels/{node.original}";
                        (await github.DeleteAsync(method)).EnsureSuccessStatusCode();
                    }

                    if (null != node.label)
                    {
                        // Update existing label
                        var content = new StringContent($"{{ \"new_name\": \"{name}\", \"description\": \"{description}\", \"color\": \"{color}\" }} ");
                        (await github.PatchAsync($"/repos/{owner}/{node.repo}/labels/{node.label}", content))
                        .EnsureSuccessStatusCode();
                        count += 1;
                    }
                    else
                    {
                        // Create label
                        var content = new StringContent($"{{ \"name\": \"{node.label}\", \"description\": \"{description}\", \"color\": \"{color}\" }} ");
                        (await github.PostAsync($"/repos/{owner}/{node.repo}/labels", content))
                        .EnsureSuccessStatusCode();
                        count += 1;
                    }
                }
            }
            else
            {
                // Process changes in color or description
                await foreach (var node in github.GetNodes(payload))
                {
                    var repo    = node[GitHubApi.NAME].Value <string>();
                    var content = new StringContent($"{{ \"name\": \"{name}\", \"description\": \"{description}\", \"color\": \"{color}\" }} ");
                    var label   = node[GitHubApi.LABEL];

                    if (null != label && label.HasValues)
                    {
                        // Update existing label
                        (await github.PatchAsync($"/repos/{owner}/{repo}/labels/{name}", content))
                        .EnsureSuccessStatusCode();
                        count += 1;
                    }
                    else
                    {
                        // Create label
                        (await github.PostAsync($"/repos/{owner}/{repo}/labels", content))
                        .EnsureSuccessStatusCode();
                        count += 1;
                    }
                }
            }

            var message = $"Successfully updated in {count} repositories";

            log.LogInformation(message);
        }