CSC/ECE 517 Spring 2019 - Project E1925. Refactor E1858. Github metrics integration

From Expertiza_Wiki
Jump to navigation Jump to search

Introduction

Problem Statement

Expertiza provides teammate reviews to gauge how much each team member contributed, this information could be generated from data from external tools like Github (for example, number of commits, number of lines of code modified, number of lines added, number of lines deleted.) from each group’s submitted repo link. Currently, Expertiza provides Teammate Reviews under View Scores functionality for each assignment.

1. Teammate Reviews functionality in the View Scores page gauges teammate views on how much other team members contributed to the project. We need to augment this data with data from external tools like GitHub in order to validate that feedback. New metrics will be appended under each student data under the same functionality.
2. Github Metrics under View Submissions page should include a bar chart that shows the number of commits by the team throughout the assignment timeline. This will help instructors to get a team overview, and aid grading process.

While this data will not have marks associated directly, it will prove useful to the instructor in differentiating the performance of team members and hence awarding marks as per contribution. Overall data for the team, like the number of committers and number of commits may also help instructors to predict which projects are likely to be merged.

The link for our project PR is here

Project Task

Extract Github metadata of the submitted repos and pull requests.

  1. The metadata should be stored in the local Expertiza DB. For each participant, record should include at least:
    • Committer id
    • Total number of commits
    • Number of files changed
    • Lines of code changed
    • Lines of code added
    • Lines of code removed
    • Lines of code added that survived until final submission [if available from Github]
  2. The code should sync the data with Github whenever someone (student or instructor) looks at a view that shows Github data.
  3. The data for teams should be shown in the instructor’s View Scores window, in a new tab, probably between Reviews and Author Feedback.
    • Design a good view for showing data on individuals. Please discuss this with the project mentor(s).
    • It seems to me that this should be on the Teammate Reviews tab, right below the grid for teammate reviews. The reason for this is that we’d like to see all the data on an individual in a single view. For teams, by contrast, there is already a pretty large grid, and potentially multiple grids for multiple rounds, so adding a new grid is more likely to clutter the display.
  4. Create a bar chart for the # of lines changed for each assignment team on “view_submissions” page. The x-axis should be the time starting from the assignment creation time, till the last deadline of the assignment, or current time, whichever is earlier.

This task has been partially implemented by another group for project E1858. Github Metrics Integration in 2018 Fall semester. Detailed document about project E1858 on framework design and implementation can be found in here and the PR for Project E1858 is shown in Here. However, their work has been rejected with the feedback "They have integrated the github metrics into expertiza to show the number of commits, pull requests status, etc against every project. They have also integrated it into the metrics. Looks like they covered the edge cases. The code looks good but needs comments as it is pretty complex. The documentation feels like it is flooded with code, if there was a description of the changes, it would have been better. Extensive tests, but it might be good to see if additions to existing tests really belong in those same tests". The goal of our current project is to resolve issues existing in their previous work, refactor codes they created and modify their code following "DRY" principles. The ultimate goal is to have the Github Metric Integration work in Expertiza.

Team

  • swang28 (Shuai Wang)
  • zwu17 (Ziwei Wu)
  • hlu6 (Hao Lu)
  • ychen239( Yuhan Chen)
  • zhu6 (Zhewei Hu, mentor)


Plan of Work

Use Case Diagram

1. Use Case diagram of two approaches to append 'GitHub contribution metric' in teammate review. 2. Use Case diagram explaining approach to add new column 'GitHub contribution metric' in 'View submission

Use Case Diagram Details

Actors:

  • Instructor: This actor is responsible for viewing GitHub metrics of teams and team members of an assignment.

Pre-Conditions:

  • The Team should have submitted the assignment with a PR link or GitHub repository.

Primary Sequence:

  • The instructor should login.
  • The instructor should browse teams for an assignment.

Post Conditions:

  • Instructor will be able to see the team contribution done by each team member in 'View Submissions' page using graph diagrams, as shown in the figure.
  • Instructor will be able to see the work done by each student in 'Teammate Review Tab' with new metrics table appended at the end, as shown in the figure.

Github Metrics Features

Github Metrics Features can be accessed from manage content UI

Then click the 'view submissions'

Then we can see 'Github Metrics button' in each project submission

Below is the bar chart of commit numbers.

We can see the details in the following part.

Our Improvements

After understanding the project E1851, We found some issues in this project and give our solutions below.

Add New Controller

Problem: The related codes for Github related functionalities are most implemented under "Grades_Controller". This design obviously violates a good design pattern because Grade_Controller involves too many functions.

Solution: To improve it, we should create a separate "Github_Metrics_Controller" which is specifically responsible for functions related to Github Metrics. Following the MVC architecture, we will also need to create corresponding Models and Views for the new controller.

Move JavaScript Code

Problem: There are some JavaScript codes in inappropriate positions. For example:

<script type="text/javascript">
  toggle_tag_prompt = function() {
    $('.tag_prompt_container').toggle();
  };
  $( document ).ready(function() {
    $('#tag_prompt_toggler').click(function () {
      if ($('#tag_prompt_toggler').text() == "hide tags")
        $('#tag_prompt_toggler').text("show tags")
      else
        $('#tag_prompt_toggler').text("hide tags")
    });
  });
</script>

Solution: We need to replace JavaScript codes to 'assets' fold.

"Dry" the Redundant Code

Problem: Lots of codes in their current implementation violate ruby's "DRY" principles, such as redundant codes, meaningless names, long coding block and so on.

Solution: We will refactor their code and fix code smells with the help of code climate platform.

For example, some code like the format below can be rewritten in the shorter line.

   @head_refs = {}
   @parsed_data = {}
   @authors = {}
   @dates = {}
   @total_additions = 0
   @total_deletions = 0
   @total_commits = 0
   @total_files_changed = 0
   @merge_status = {}
   @check_statuses = {}

The solution to the example: create a hash table for all of the instance variables and refactor all the usage of the variables.

  @gitVariable = {
       :head_refs => {},
       :parsed_data => {},
       :authors => {},
       :dates => {},
       :total_additions => 0,
       :total_deletions => 0,
       :total_commits => 0,
       :total_files_changed => 0,
       :merge_status => {},
       :check_statuses => {}
   }

Some code like the format below can be rewritten and shorten by putting } in one line.

def get_github_repository_details(hyperlink_data)
   data = {
     query: "query {
       repository(owner: \"" + hyperlink_data["owner_name"] + "\", name: \"" + hyperlink_data["repository_name"] + "\") {
         ref(qualifiedName: \"master\") {
           target {
             ... on Commit {
               id
                 history(first: 100) {
                   edges {
                     node {
                       id author {
                         name email date
                       }
                     }
                   }
                 }
               }
             }
           }
         }
       }"
   }

Also, there are many useless spaces make the code look less elegant.

Test Plan

To make sure the refactor code can work correctly, we need to run the original rspec test code and add some new test. Besides, we are plaining to test from UI to make sure all the features work. The test results are shown below.

  • Run and pass existing RSpec Tests after refactoring
  • Develop New RSpec Tests for the new features
  • UI testing on the deployed project

Rspec Test

For the existting test, we need to mock roles:

 let(:review_response) { build(:response) }
 let(:assignment) { build(:assignment, id: 1, questionnaires: [review_questionnaire], is_penalty_calculated: true) }
 let(:assignment_questionnaire) { build(:assignment_questionnaire, used_in_round: 1, assignment: assignment) }
 let(:participant) { build(:participant, id: 1, assignment: assignment, user_id: 1) }
 let(:participant2) { build(:participant, id: 2, assignment: assignment, user_id: 1) }
 let(:review_questionnaire) { build(:questionnaire, id: 1, questions: [question]) }
 let(:admin) { build(:admin) }
 let(:instructor) { build(:instructor, id: 6) }
 let(:question) { build(:question) }
 let(:team) { build(:assignment_team, id: 1, assignment: assignment, users: [instructor]) }
 let(:student) { build(:student) }
 let(:review_response_map) { build(:review_response_map, id: 1) }
 let(:assignment_due_date) { build(:assignment_due_date) }

All the test can be found in "expertiza/spec/controllers/grades_controller_spec.rb" now, we will refactor it since we need to build new controller.

We test several conditions :

  • Views
    • when user has logged into to GitHub
    • when user hasn\'t logged in to GitHub
    • when current assignment does not vary rubric by round
  • view_my_scores
    • when view_my_scores page is not allow to access
    • when view_my_scores page is allow to access
  • view_team
  • edit
  • instructor_review
    • when review exists
    • when review does not exist
  • update
    • when total is not equal to participant\'s grade
    • when total is equal to participant\'s grade
  • save_grade_and_comment_for_submission
  • get_statuses_for_pull_request
  • etrieve_pull_request_data
  • retrieve_repository_data
  • retrieve_github_data
    • when pull request links have been submitted
    • when pull request links have not been submitted
  • retrieve_check_run_statuses
  • view_github_metrics
    • when user has logged in to GitHub
  • authorize_github
  • get_github_repository_details
  • get_pull_request_details
  • process_github_authors_and_dates
  • parse_github_pull_request_data
  • parse_github_repository_data
  • make_github_graphql_request
  • get_query
  • team_statistics
  • organize_commit_dates

The new rspec test file is here. You can run the following code

rspec spec/controllers/github_metrics_controller_spec.rb

to test the result. Our rspec test coverage is 100. The test video is here

UI Test

For this project, we add an API from the GitHub, all we need to do is to test whether the API can work appropriately after changing codes to another controller and moving javascript codes.

Management -> Assignment -> Github Metrics

You can see the test result in Project E1925 Video

Implementation

Add New Controller

We added and changed the new controller github_metrics controller and some ralated files.

The GitHub metrics part is separated into the new files.

Move JavaScript Code

Previous work includes JavaScript code. After carefully testing and examination, we found these JavaScript code were another version of the implementation of our task. So we remove those redundant codes to make our code clean.

Refactor Redandent Variables

We create a hash table to cover all the created instance variables.

Callback setup for github token

we set the callback URL as: ./auth/github/callback

References

Project E1925 Video

rspec test

Expertiza_wiki

Project E1858 wiki

Project E1858 PR Link

GitHub API documentation