৬.৫ গিটহাব – স্ক্রিপ্টিং গিটহাব

আমরা GitHub-এর সমস্ত প্রধান বৈশিষ্ট্য এবং ওয়ার্কফ্লো (workflows) কভার করেছি, তবে যে কোনও বড় গ্রুপ  বা প্রোজেক্টে কাস্টমাইজেশন থাকতে পারে অথবা এক্সটারনাল সার্ভিস ইন্টিগ্রেশন প্রয়োজন হতে পারে।

সৌভাগ্যবশত, GitHub অনেক উপায়ে বেশ সহজে পরিবর্তনযোগ্য (hackable) । এই অধ্যায়ে আমরা কভার করব কিভাবে গিটহাব হুক (Hook) সিস্টেম এবং এর API ব্যবহার করে গিটহাবকে ইচ্ছেমত কাজে লাগাতে পারি।

সার্ভিস এবং হুক (Service and Hooks)

গিটহাব রিপোজিটরি অ্যাডমিনিস্ট্রেশনের হুকস এবং সার্ভিসেস হল গিটহাবকে এক্সটারনাল সিস্টেমের সাথে ইন্টারঅ্যাক্ট করার সবচেয়ে সহজতম উপায়।

সার্ভিসসমূহ (Services)

প্রথমে আমরা সার্ভিসগুলো দেখে নেব। আপনার রিপোজিটরির সেটিংসে হুক এবং সার্ভিস ইন্টিগ্রেশন উভয়ই পাওয়া যাবে, যেখানে আমরা পূর্বে Collaborators যোগ করার এবং আপনার প্রোজেক্টের ডিফল্ট ব্রাঞ্চ পরিবর্তন করার বিষয়ে দেখেছি। “Webhooks and Services” ট্যাবের অধীনে আপনি সার্ভিস এবং হুকস কনফিগারেশন বিভাগ দেখতে পাবেন।
scripting-01-services
চিত্র 129. সার্ভিস এবং হুক কনফিগারেশন বিভাগ

আপনি বেছে নিতে পারেন এমন ডজন ডজন সার্ভিস রয়েছে, যার বেশিরভাগই অন্যান্য বাণিজ্যিক এবং ওপেন সোর্স সিস্টেমে ইন্টিগ্রেশন হয়৷ তাদের বেশিরভাগই কন্টিনিউয়াস ইন্টিগ্রেশন সার্ভিস, বাগ এবং ইস্যু ট্র্যাকার, চ্যাট রুম সিস্টেম এবং ডকুমেন্টেশন সিস্টেমের জন্য। আমরা একটি খুব সাধারণ একটি ইমেল হুক সেট আপ করার মাধ্যমে শুরু করব৷ আপনি যদি “Add Service” ড্রপডাউন থেকে “email” বেছে  নেন, আপনি ইমেল সার্ভিস কনফিগারেশনের মতো একটি কনফিগারেশন স্ক্রিন পাবেন।

scripting 02 email service 1 Scripting-GitHub
চিত্র 130. ইমেল সার্ভিস কনফিগারেশন

এই ক্ষেত্রে, যদি আমরা “add service” বাটনটি  চাপি, তখন প্রতিটি পুশের জন্যে আমাদের ঠিক করা ইমেইলে একটি নোটিফিকেশন যাবে। সার্ভিসগুলি,  অনেকগুলি বিভিন্ন ধরণের ইভেন্টের জন্য নোটিফিকেশন পেতে পারে, তবে বেশিরভাগই কেবল পুশ ইভেন্টগুলির জন্য নোটিফিকেশন পায় এবং তারপর সেই ডেটা দিয়ে কিছু করে৷

আপনি যদি কোন সার্ভিস গিটহাব এর সাথে ইন্টিগ্রেট করতে চান, তবে প্রথমে চেক করুন যে বিদ্যমান কোন সার্ভিস দিয়ে তা করা সম্ভব কিনা।  উদাহরণস্বরূপ, আপনি যদি আপনার কোডবেসে পরীক্ষা চালানোর জন্য জেনকিন্স ব্যবহার করেন , আপনি জেনকিন্স বিল্টইন সার্ভিস  ইন্টিগ্রেশন এনাবল  করতে পারেন যাতে কেউ আপনার রিপোসিটোরিতে  পুশ করলেই প্রতিবার পরীক্ষা চালানো শুরু হয়ে যায়।

হুকস

আপনার যদি আরও নির্দিষ্ট কিছুর প্রয়োজন হয় বা আপনি এমন একটি সার্ভিস বা সাইটের সাথে ইন্টিগ্রেট করতে চান যা এই তালিকায় অন্তর্ভুক্ত নয়, আপনি পরিবর্তে আরও জেনেরিক হুক সিস্টেম ব্যবহার করতে পারেন। গিটহাব রিপোজিটরি হুকগুলি বেশ সহজ। আপনি একটি URL ঠিক করুন এবং GitHub আপনার ঠিক করা  ইভেন্টে সেই URL-এ একটি HTTP পেলোড পোস্ট করবে। সাধারণত এটি যেভাবে কাজ করে, আপনি একটি GitHub হুক পেলোড লিসেনের (listen) জন্য একটি ছোট ওয়েব সার্ভিস সেটআপ করতে পারেন এবং তারপরে এটিতে পোস্ট  হলে সেই ডেটা দিয়ে কিছু করতে পারেন। একটি হুক এনাবল  করতে, আপনি সার্ভিস এবং হুক কনফিগারেশন বিভাগে “add webhook” বাটনটি  ক্লিক করুন ৷ এটি আপনাকে একটি পেজে  নিয়ে আসবে যা দেখতে ওয়েব হুক কনফিগারেশনের মতো ।
scripting 03 webhook 1 Scripting-GitHub
চিত্র ১৩১. ওয়েব হুক কনফিগারেশন

একটি ওয়েব হুকের কনফিগারেশন বেশ সহজ। বেশিরভাগ ক্ষেত্রে আপনি কেবল একটি URL এবং একটি সিক্রেট-কী লিখুন এবং “add webhook” চাপুন। কিছু বিকল্প রয়েছে যেগুলির জন্য আপনি চান যে ইভেন্টগুলির জন্য GitHub আপনাকে একটি পেলোড পাঠাতে — ডিফল্ট হল শুধুমাত্র push ইভেন্টের জন্য একটি পেলোড পাওয়া, যখন কেউ আপনার রিপোজিটরির যেকোনো শাখায় নতুন কোড পুশ করে।

আসুন একটি ওয়েব সার্ভিসের একটি ছোট উদাহরণ দেখি যাতে  আপনি একটি ওয়েব হুক সেট আপ করতে পারেন৷ আমরা রুবি ওয়েব ফ্রেমওয়ার্ক সিনাট্রা ব্যবহার করব যেহেতু এটি মোটামুটি সংক্ষিপ্ত এবং আমরা কী করছি তা আপনি সহজেই দেখতে সক্ষম হবেন।

ধরা যাক আমরা একটি ইমেল পেতে চাই যদি কোনো নির্দিষ্ট ব্যক্তি একটি নির্দিষ্ট ফাইল পরিবর্তন করে আমাদের রিপোসিটোরির  একটি নির্দিষ্ট ব্রাঞ্চে  পুশ করে। আমরা নিচের কোডটির মতন কিছু ব্যবহার করতে পারি।

				
					require 'sinatra'
require 'json'
require 'mail'

post '/payload' do
  push = JSON.parse(request.body.read) # parse the JSON

  # gather the data we're looking for
  pusher = push["pusher"]["name"]
  branch = push["ref"]

  # get a list of all the files touched
  files = push["commits"].map do |commit|
    commit['added'] + commit['modified'] + commit['removed']
  end
  files = files.flatten.uniq

  # check for our criteria
  if pusher == 'schacon' &&
       branch == 'ref/heads/special-branch' &&
     files.include?('special-file.txt')

    Mail.deliver do
      from     'tchacon@example.com'
      to       'tchacon@example.com'
      subject  'Scott Changed the File'
      body     "ALARM"
    end
  end
end
				
			

এখানে আমরা JSON পেলোড নিচ্ছি যা GitHub থেকে পাওয়া এবং কে এটিকে পুশ করেছে , তারা কোন ব্রাঞ্চে পুশ করেছে  এবং পুশ করা সমস্ত কমিটগুলিতে কোন ফাইলগুলি স্পর্শ করা হয়েছে তা দেখছি। তারপরে আমরা আমাদের ক্রাইটেরিয়া অনুযায়ী যদি মেলে তবে একটি ইমেল পাঠাই।

এইরকম কিছু ডেভেলপ  এবং টেস্ট  করার জন্য, আপনার কাছে একই স্ক্রিনে একটি ডেভেলপিং কনসোল রয়েছে যেখানে আপনি হুক সেট করেছেন৷ আপনি শেষ কয়েকটি ডেলিভারি দেখতে পারেন যা GitHub সেই ওয়েবহুকের জন্য তৈরি করার চেষ্টা করেছে। প্রতিটি সফল  হুকের জন্য আপনি দেখতে  পারেন কখন এটি ডেলিভার  করা হয়েছিল, এবং রিকোয়েস্ট এবং রেস্পন্স  উভয়ের বডি এবং হেডার। এটি আপনার হুকগুলি পরীক্ষা এবং ডিবাগ করা অবিশ্বাস্যভাবে সহজ করে তোলে।

scripting-04-webhook-debug
চিত্র 132. ওয়েব হুক ডিবাগিং তথ্য
এটির আরেকটি দুর্দান্ত বৈশিষ্ট্য হল যে আপনি সহজেই আপনার সার্ভিস পরীক্ষা করার জন্য যে কোনও পেলোড পুনরায় ডেলিভারি করতে পারেন। ওয়েবহুকগুলি কীভাবে লিখতে হয় এবং আপনি যে সমস্ত ধরণের ইভেন্টের জন্য শুনতে পারেন সে সম্পর্কে আরও তথ্যের জন্য, https://developer.github.com/webhooks/- এ গিটহাব ডেভেলপার ডকুমেন্টেশনে যান ।

GitHub API

সার্ভিস এবং হুকগুলি আপনাকে আপনার রিপোজিটরিগুলিতে ঘটে যাওয়া ইভেন্টগুলি সম্পর্কে পুশ নোটিফিকেশন এর মাধ্যমে তথ্য দেয় , তবে এই ইভেন্টগুলি সম্পর্কে আপনার আরও তথ্যের প্রয়োজন হলে কী হবে? সহযোগীদের যোগ করা বা লেবেল সংক্রান্ত সমস্যাগুলির মতো কিছু স্বয়ংক্রিয় করার প্রয়োজন হলে কী হবে? এখানেই GitHub API কাজে আসে। ওয়েবসাইটে আপনি যা করতে পারেন তার প্রায় সব কিছু করার জন্য GitHub-এর প্রচুর API এন্ডপয়েন্ট রয়েছে। এই বিভাগে আমরা শিখব কিভাবে অথেন্টিকেট করা যায় এবং API এর সাথে সংযোগ করা যায়, কীভাবে একটি ইস্যুতে  কমিট করতে হয় এবং API-এর মাধ্যমে একটি পুল রিকোয়েস্টের  অবস্থা কীভাবে পরিবর্তন করতে হয়।

বেসিক  ব্যবহার

সবচেয়ে বেসিক আপনি যা করতে পারেন, এমন একটি GET রিকোয়েস্ট পারফর্ম করবেন যার জন্যে কোন অথেন্টিকেশন লাগেনা।  এটি একটি ব্যবহারকারী বা একটি ওপেন সোর্স প্রকল্পে read -only তথ্য হতে পারে। উদাহরণস্বরূপ, যদি আমরা “schacon” নামের একজন ব্যবহারকারী সম্পর্কে আরও জানতে চাই, তাহলে আমরা এরকম কিছু চালাতে পারি:
				
					$ curl https://api.github.com/users/schacon
{
  "login": "schacon",
  "id": 70,
  "avatar_url": "https://avatars.githubusercontent.com/u/70",
# ...
  "name": "Scott Chacon",
  "company": "GitHub",
  "following": 19,
  "created_at": "2008-01-27T17:19:28Z",
  "updated_at": "2014-06-10T02:37:23Z"
}
				
			

অরগানাইজেশন , প্রজেক্ট , ইস্যু , কমিট  সম্পর্কে তথ্য পাওয়ার জন্য এর মতো অনেকগুলি এন্ডপয়েন্ট রয়েছে — যা আপনি GitHub-এ পাবলিকলি  দেখতে পারেন। এমনকি আপনি ইচ্ছামত  মার্কডাউন রেন্ডার করতে বা একটি .gitignore টেমপ্লেট খুঁজে পেতে API ব্যবহার করতে পারেন।

				
					$ curl https://api.github.com/gitignore/templates/Java
{
  "name": "Java",
  "source": "*.class

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.ear

# virtual machine crash logs, see https://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
"
}
				
			

ইস্যুতে  কমিট করা

যাইহোক, আপনি যদি ওয়েবসাইটে কোনো কাজ করতে চান যেমন কোনো ইস্যুতে কমিট করা বা পুল রিকোয়েস্ট বা আপনি যদি ব্যক্তিগত বিষয়বস্তু দেখতে বা ইন্টারঅ্যাক্ট করতে চান, তাহলে আপনাকে অথেন্টিকেট  করতে হবে। অথেন্টিকেশনের বিভিন্ন উপায় আছে। আপনি শুধুমাত্র আপনার ব্যবহারকারীর নাম এবং পাসওয়ার্ড দিয়ে বেসিক  অথেনটিকেশন ব্যবহার করতে পারেন, তবে সাধারণত ব্যক্তিগত অ্যাক্সেস টোকেন ব্যবহার করা ভাল. আপনি আপনার সেটিংস পৃষ্ঠার “Applications” ট্যাব থেকে এটি তৈরি করতে পারেন।
scripting-05-access-token
চিত্র 133. আপনার সেটিংস পৃষ্ঠার "অ্যাপ্লিকেশন" ট্যাব থেকে আপনার অ্যাক্সেস টোকেন তৈরি করুন
এটি আপনাকে জিজ্ঞাসা করবে যে আপনি এই টোকেন এবং একটি বিবরণের জন্য কোন স্কোপ চান৷ একটি ভাল বিবরণ ব্যবহার করুন যাতে আপনার স্ক্রিপ্ট বা অ্যাপ্লিকেশন আর ব্যবহার করা না হলে আপনি টোকেনটি সহজে ফেলে দিতে পারেন । GitHub আপনাকে শুধুমাত্র একবার টোকেন দেখাবে, তাই এটি কপি করতে ভুলবেন না। আপনি এখন ব্যবহারকারীর নাম এবং পাসওয়ার্ড ব্যবহার করার পরিবর্তে আপনার স্ক্রিপ্টে অথেন্টিকেট করতে এটি ব্যবহার করতে পারেন। এটি বেটার  কারণ আপনি যা করতে চান তার সুযোগ সীমিত করতে পারেন এবং টোকেনটি প্রত্যাহারযোগ্য। এটি ব্যবহার করলে আপনার ব্যবহারসীমাও বাড়বে  রয়েছে। অথেনটিকেশন ছাড়া, আপনি প্রতি ঘন্টায় 60টি অনুরোধের মধ্যে সীমাবদ্ধ থাকবেন। আপনি অথেনটিকেট করলে আপনি প্রতি ঘন্টায় 5,000টি পর্যন্ত রিকোয়েস্ট  করতে পারবেন। সুতরাং আসুন আমাদের একটি ইস্যুতে একটি কমিট করতে এটি ব্যবহার করা যাক. ধরা যাক আমরা একটি নির্দিষ্ট ইস্যুতে একটি কমিট করতে চাই, ইস্যু #6৷ এটি করার জন্য আমাদের একটি টোকেন সহ একটি HTTP POST অনুরোধ করতে হবে repos/<user>/<repo>/issues/<num>/comments যা আমরা একটি অথোরাইজেশন হেডার  হিসাবে তৈরি করেছি।
				
					$ curl -H "Content-Type: application/json" \
       -H "Authorization: token TOKEN" \
       --data '{"body":"A new comment, :+1:"}' \
       https://api.github.com/repos/schacon/blink/issues/6/comments
{
  "id": 58322100,
  "html_url": "https://github.com/schacon/blink/issues/6#issuecomment-58322100",
  ...
  "user": {
    "login": "tonychacon",
    "id": 7874698,
    "avatar_url": "https://avatars.githubusercontent.com/u/7874698?v=2",
    "type": "User",
  },
  "created_at": "2014-10-08T07:48:19Z",
  "updated_at": "2014-10-08T07:48:19Z",
  "body": "A new comment, :+1:"
}
				
			
এখন আপনি যদি সেই ইস্যুতে যান, আপনি সেই মন্তব্যটি দেখতে পাবেন যা আমরা সফলভাবে GitHub API ব্যবহার করে পোস্ট করেছি ।
scripting-06-comment
চিত্র 134. GitHub API থেকে পোস্ট করা একটি কমিট

আপনি ওয়েবসাইটে যা কিছু করতে পারেন তার জন্য আপনি API ব্যবহার করতে পারেন — মাইলস্টোন তৈরি করা এবং সেট করা, ইস্যু এবং পুল রিকোয়েস্টে লোকেদের এলোকেট  করা, লেবেল তৈরি এবং পরিবর্তন করা, কমিট ডেটা অ্যাক্সেস করা, নতুন কমিট এবং শাখা তৈরি করা, খোলা, বন্ধ করা বা মার্জ করা পুল রিকোয়েস্ট, টিম তৈরি ও এডিট করা, পুল রিকোয়েস্টে কোডের লাইনে কমিট করা, সাইট সার্চ করা এবং আরো অনেক কাজ ।

পুল রিকোয়েস্টের স্ট্যাটাস পরিবর্তন

আমরা একটি শেষ  উদাহরণ দেখব কারণ এটি সত্যিই দরকারী যদি আপনি পুল রিকোয়েস্টগুলির সাথে কাজ করেন। প্রতিটি কমিট এর সাথে যুক্ত এক বা একাধিক স্ট্যাটাস থাকতে পারে এবং সেই স্ট্যাটাস যোগ করতে এবং কুয়েরি (query) করার জন্য একটি API আছে।

বেশিরভাগ কন্টিনিউয়াস ইন্টিগ্রেশন এবং টেস্টিং সার্ভিসগুলি এই API ব্যবহার করে পুশ দেওয়া কোডটি পরীক্ষা করে পুশের প্রতি প্রতিক্রিয়া জানাতে এবং তারপরে রিপোর্টটির সমস্ত ক্রাইটেরিয়া যদি ঠিক থাকে তাহলে রিপোর্ট করে৷ আপনি কমিট মেসেজটি  সঠিকভাবে ফর্ম্যাট করা হয়েছে কিনা তা পরীক্ষা করতেও এটি ব্যবহার করতে পারেন। 

ধরা যাক আপনি আপনার রিপোজিটরিতে একটি ওয়েবহুক সেট আপ করেছেন যা একটি ছোট ওয়েব সার্ভিসকে হিট  করে Signed-off-by যা কমিট মেসেজে একটি স্ট্রিং পরীক্ষা করে।

				
					require 'httparty'
require 'sinatra'
require 'json'

post '/payload' do
  push = JSON.parse(request.body.read) # parse the JSON
  repo_name = push['repository']['full_name']

  # look through each commit message
  push["commits"].each do |commit|

    # look for a Signed-off-by string
    if /Signed-off-by/.match commit['message']
      state = 'success'
      description = 'Successfully signed off!'
    else
      state = 'failure'
      description = 'No signoff found.'
    end

    # post status to GitHub
    sha = commit["id"]
    status_url = "https://api.github.com/repos/#{repo_name}/statuses/#{sha}"

    status = {
      "state"       => state,
      "description" => description,
      "target_url"  => "http://example.com/how-to-signoff",
      "context"     => "validate/signoff"
    }
    HTTParty.post(status_url,
      :body => status.to_json,
      :headers => {
        'Content-Type'  => 'application/json',
        'User-Agent'    => 'tonychacon/signoff',
        'Authorization' => "token #{ENV['TOKEN']}" }
    )
  end
end


				
			
আশা করি এটি অনুসরণ করা মোটামুটি সহজ। এই ওয়েব হুক হ্যান্ডলারে আমরা প্রতিটি কমিটের মাধ্যমে দেখি যা সবেমাত্র পুশ করা হয়েছিল, আমরা কমিট মেসেজে ‘সাইন-অফ-বাই’ স্ট্রিংটি সন্ধান করি এবং অবশেষে আমরা /repos/<user>/<repo>/statuses/<commit_sha> স্ট্যাটাস সহ HTTP এর মাধ্যমে API এন্ডপয়েন্টে পোস্ট করি। এই ক্ষেত্রে আপনি একটি স্টেট  (‘success’, ‘failure’, ‘error’ ), কী ঘটেছে তার একটি বিবরণ, ব্যবহারকারী আরও তথ্যের জন্য একটি টার্গেট  URL এবং একটি একক কমিটের জন্য একাধিক স্ট্যাটাস থাকলে একটি “কনটেক্সট ” পাঠাতে পারেন।  উদাহরণ স্বরূপ, একটি টেস্টিং সার্ভিস একটি স্ট্যাটাস প্রদান করতে পারে এবং এর মতো একটি ভ্যালিডেশন সার্ভিসও একটি স্ট্যাটাস প্রদান করতে পারে — “কনটেক্সট” ফিল্ডটি হল তারা কীভাবে আলাদা করা হয়। যদি কেউ গিটহাবে একটি নতুন পুল রিকোয়েস্ট খোলে এবং এই হুক সেট আপ করা হয়, আপনি API এর মাধ্যমে কমিট স্ট্যাটাসের মতো কিছু দেখতে পারেন ।
scripting-07-status
চিত্র 135. এপিআই এর মাধ্যমে কমিট-এর অবস্থা

আপনি এখন কমিটের পাশে একটি ছোট সবুজ চেক চিহ্ন দেখতে পাবেন যেটিতে বার্তাটিতে একটি “Signed-off-by” স্ট্রিং রয়েছে এবং যেখানে লেখক সাইন অফ করতে ভুলে গেছেন তার মধ্য দিয়ে একটি লাল ক্রস রয়েছে৷ আপনি আরও দেখতে পারেন যে পুল রিকোয়েস্ট শাখায় শেষ কমিটের স্টেট্  নেয় এবং এটি ব্যর্থ হলে আপনাকে সতর্ক করে। এটি সত্যিই দরকারী যদি আপনি পরীক্ষার ফলাফলের জন্য এই API ব্যবহার করছেন যাতে আপনি দুর্ঘটনাক্রমে এমন কিছু মার্জ করবেন না যেখানে শেষ কমিট টেস্ট ফেইল করে।

অক্টোকিট

যদিও আমরা এই উদাহরণগুলিতে এবং সাধারণ HTTP রিকুয়েষ্টগুলির প্রায় সবকিছুই curl দিয়ে করছি  , বেশ কয়েকটি ওপেন-সোর্স লাইব্রেরি আছে যা এই API টিকে আরও সাচ্ছন্দে ব্যবহার  করে। এই লেখা লেখার সময়, সমর্থিত ভাষাগুলির মধ্যে রয়েছে Go, Objective-C, Ruby এবং .NET। এগুলি সম্পর্কে আরও তথ্যের জন্য https://github.com/octokit দেখুন , কারণ তারা আপনার জন্য বেশিরভাগ HTTP পরিচালনা করে।

আশা করি এই টুলগুলি আপনাকে আপনার নির্দিষ্ট ওয়ার্কফ্লোগুলির জন্য আরও ভাল কাজ করতে গিটহাবকে কাস্টমাইজ এবং সংশোধন করতে সহায়তা করবে। সম্পূর্ণ API-এ সম্পূর্ণ ডকুমেন্টেশনের পাশাপাশি সাধারণ কাজের জন্য গাইডের জন্য, https://developer.github.com দেখুন