devimur2021 / Sentiment-Based-Product-Recommendation-System

Sentiment based product recommendation system
0 stars 0 forks source link

Get Latest GitHub Action run for a given commit SHA #5

Closed gargvasu closed 2 months ago

gargvasu commented 2 months ago

In GitLab, we have an HTTP API that provides detailed status information for a given repository and commit SHA. From this information, we extract the "updated at" timestamp.

We need to implement similar functionality for GitHub. However, we could not find a direct API that offers the same details. Instead, we found an API that retrieves all runs for a repository. Using this API, we must iterate through the response to find GitHub Action runs that match the specified commit SHA. Additionally, the API supports pagination and by default returning 30 runs per request. So we called API called again and again until we got all the runs.

To improve efficiency, we switched to using the GitHub GraphQL API. This API allows us to fetch all runs for a given commit SHA effectively. While this method works, it lacks an option to order the results by a updated at timestamp, which we need.

igorcosta commented 2 months ago

Let's try this one, I've asked Copilot to translate my Python code to Perl.

#!/usr/bin/env perl
use strict;
use warnings;
use LWP::UserAgent;
use JSON::PP;
use DateTime::Format::ISO8601;
use Data::Dumper;

package GitHubActionRunFetcher;

sub new {
    my ($class, $token) = @_;
    my $self = {
        token => $token,
        ua => LWP::UserAgent->new,
        endpoint => 'https://api.github.com/graphql',
    };
    bless $self, $class;
    return $self;
}

sub fetch_latest_run {
    my ($self, $owner, $repo, $commit_sha) = @_;

    my $query = qq{
        query(\$owner: String!, \$repo: String!, \$commit_sha: GitObjectID!) {
          repository(owner: \$owner, name: \$repo) {
            object(oid: \$commit_sha) {
              ... on Commit {
                checkSuites(first: 100) {
                  nodes {
                    workflowRun {
                      createdAt
                      updatedAt
                      url
                      status
                      conclusion
                    }
                  }
                }
              }
            }
          }
        }
    };

    my $variables = {
        owner => $owner,
        repo => $repo,
        commit_sha => $commit_sha,
    };

    my $json = JSON::PP->new->utf8->encode({
        query => $query,
        variables => $variables,
    });

    my $req = HTTP::Request->new(
        'POST',
        $self->{endpoint},
        [
            'Authorization' => "Bearer $self->{token}",
            'Content-Type' => 'application/json',
        ],
        $json
    );

    my $res = $self->{ua}->request($req);

    if ($res->is_success) {
        my $data = decode_json($res->content);
        my $check_suites = $data->{data}{repository}{object}{checkSuites}{nodes};

        my @valid_runs = grep { $_->{workflowRun} } @$check_suites;
        @valid_runs = sort {
            DateTime::Format::ISO8601->parse_datetime($b->{workflowRun}{updatedAt})
            <=>
            DateTime::Format::ISO8601->parse_datetime($a->{workflowRun}{updatedAt})
        } @valid_runs;

        if (@valid_runs) {
            my $latest_run = $valid_runs[0]->{workflowRun};
            return {
                created_at => $latest_run->{createdAt},
                updated_at => $latest_run->{updatedAt},
                url => $latest_run->{url},
                status => $latest_run->{status},
                conclusion => $latest_run->{conclusion},
            };
        } else {
            return undef;
        }
    } else {
        die "Query failed: " . $res->status_line . "\n" . $res->content;
    }
}

package main;

# Usage example
my $token = $ENV{GITHUB_TOKEN} or die "GITHUB_TOKEN environment variable is not set";
my $fetcher = GitHubActionRunFetcher->new($token);

my $owner = "example_owner";
my $repo = "example_repo";
my $commit_sha = "example_commit_sha";

my $latest_run = $fetcher->fetch_latest_run($owner, $repo, $commit_sha);

if ($latest_run) {
    print "Latest run for commit $commit_sha:\n";
    print "Created at: $latest_run->{created_at}\n";
    print "Updated at: $latest_run->{updated_at}\n";
    print "URL: $latest_run->{url}\n";
    print "Status: $latest_run->{status}\n";
    print "Conclusion: $latest_run->{conclusion}\n";
} else {
    print "No runs found for commit $commit_sha\n";
}
devimur2021 commented 2 months ago

@gargvasu validate and confirm

gargvasu commented 2 months ago

Tried this solution and i was able to get the required data