Git
Chapters ▾ 2nd Edition

6.5 GitHub - GitHub Skriptləmə

GitHub Skriptləmə

Beləliklə, indi GitHub’un əsas xüsusiyyətləri və iş axınlarının hamısını əhatə etdik, ancaq hər hansı bir böyük qrup və ya layihənin istədikləri və ya inteqrasiya etmək istədikləri xarici xidmətlər ola bilər.

Bizim üçün xoşbəxtlikdən, GitHub bir çox cəhətdən həqiqətən hack-lənə bilər. Bu hissədə GitHub-un istədiyi şəkildə işləməsi üçün GitHub hooks sistemindən və onun API-dən necə istifadə edəcəyimizi əhatə edəcəyik.

Servislər and Hook-lar

GitHub depo idarəsinin Servislər and Hook-larr bölməsi GitHub’un xarici sistemlərlə qarşılıqlı əlaqəsinin ən asan yoludur.

Servislər

Əvvəlcə Servislərə nəzər salacağıq. Həm Hook-lar, həm də Servislər inteqrasiyasını əvvəlcədən Həmkarlar əlavə etmək və layihənizin standart bölməsini dəyişdirməyə baxdığımız deponun Ayarlar bölməsində tapa bilərsiniz. “Webhooks and Services” bölməsində Servislər and Hook-lar konfiqurasiya bölməsi kimi bir şey görəcəksiniz.

Servislər and Hook-lar
Figure 130. Servislər and Hook-lar konfiqurasiya bölməsi

Seçdiyiniz onlarla servis var, əksəriyyəti digər kommersiya və açıq mənbə sistemlərinə inteqrasiya edir. Onların əksəriyyəti Davamlı İnteqrasiya xidmətləri, səhv və problem izləyiciləri, söhbət otağı sistemləri və sənədləşdirmə sistemləri üçündür. E-poçt fork-unu quraşdırmaqla çox sadə bir şəkildə keçəcəyik. “Add Service” açılan menyudan “email” seçsəniz, E-poçt xidmətinin konfiqurasiyası kimi bir konfiqurasiya ekranı alacaqsınız.

E-poçt xidməti
Figure 131. E-poçt xidmətinin konfiqurasiyası

Bu vəziyyətdə, “Add service” düyməsini vursaq, göstərilən e-poçt ünvanı, hər kimsə depoya push edərkən hər dəfə bir e-poçt alacaq. Servislər çox sayda müxtəlif hadisəni dinləyə bilər, ancaq çoxu push etmə hadisələrini dinləyir və sonra bu məlumatlarla bir şey edə bilər.

GitHub ilə inteqrasiya etmək istədiyiniz bir sistem varsa, mövcud bir servis inteqrasiyasının olub olmadığını görmək üçün buranı yoxlamalısınız. Məsələn, kod bazasında testlər aparmaq üçün Jenkins-dan istifadə edirsinizsə, Jenkins-inin servis inteqrasiyasını kimsə depolarına push etdikdə hər dəfə bir test işə salmağa imkan verə bilərsiniz.

Hook-lar

Daha spesifik bir şeyə ehtiyacınız varsa və ya bu siyahıya daxil olmayan bir servis və ya saytla inteqrasiya etmək istəsəniz, bunun əvəzinə daha ümumi hook-lar sistemindən istifadə edə bilərsiniz. GitHub depo hook-ları olduqca sadədir. Bir URL göstərmisinizsə və GitHub istədiyiniz hər hansı bir hadisədə HTTP yüklənməsini həmin URL-ə göndərəcəkdir.

Ümumiyyətlə bu iş üsulu, GitHub fork yükünü dinləmək və qəbul edildikdə məlumatla bir şey etmək üçün kiçik bir veb xidməti qura bilərsiniz.

Bir fork aktivləşdirmək üçün Servislər and Hook-lar konfiqurasiya bölməsi-dakı “Add webhook” düyməsini klikləyin. Bu sizi Web hook konfiqurasiyası kimi görünən bir səhifəyə gətirəcəkdir.

Web hook
Figure 132. Web hook konfiqurasiyası

Bir web hook üçün konfiqurasiya olduqca sadədir. Əksər hallarda sadəcə bir URL və gizli bir açar daxil edir və “Add webhook” düyməsini vurursunuz. GitHub-ın yükləməsini istədiyiniz hadisələrin bir neçə variantı var - varsayılan kimsə deponuzun hər hansı bir branch-ına yeni kodu push hadisəsi üçün bir yük almaqdır.

Bir web hook-u idarə etmək üçün qura biləcəyiniz bir veb servisin kiçik bir nümunəsini baxaq. Ruby web framework Sinatra’dan istifadə edəcəyik, çünki olduqca qısadır və etdiyimiz işləri asanlıqla görə bilərsiniz.

Müəyyən bir şəxs müəyyən bir sənəd dəyişdirərək layihəmizin müəyyən bir branch-na push etsə, e-poçt almaq istədiyimizi deyək. Bunu kifayət qədər asanlıqla bu kimi kodla edə bilərik:

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

Burada GitHub-un bizə verdiyi JSON yükünü götürürük və onu kimin push etdiyini, hansı branch-a push etdiyini və push etdikləri bütün sənədlərdə hansı sənədlərə toxunduğunu axtarırıq. Sonra meyarlarımıza uyğun olduğunu yoxlayırıq və uyğun olduqda bir e-poçt göndəririk.

Bu kimi bir şeyi inkişaf etdirmək və sınamaq üçün, fork hazırladığınız eyni ekranda gözəl bir inkişaf etdirici konsolunuz var. GitHub’un webhook üçün etdiyi cəhdləri görə bilərsiniz.

Hər bir fork üçün təhvil verildiyi anda istəyə və cavaba cavab verən body və başlıqları incəliyə bilərsiniz. Bu, hook-ları test və debug etməyi olduqca asanlaşdırır.

Webhook debug
Figure 133. Web hook debugging informasiyası

Bunun digər böyük xüsusiyyəti, xidmətinizi asanlıqla sınamaq üçün hər hansı bir payload-ı geri qaytara biləcəyinizdir.

Webhook-ların necə yazılacağı və dinləyə biləcəyiniz bütün fərqli hadisə növləri haqqında daha çox məlumat üçün https://developer.github.com/webhooks/ saytından GitHub Developer sənədlərinə baxın.

GitHub API

Servislər və hook-lar, depolarınızda baş verən hadisələr barədə push bildirişlərini almaq üçün bir yol verir, ancaq bu hadisələr haqqında daha çox məlumat lazımdırsa, nə etməlisiniz? Əməkdaşlarınızı və ya etiketləmə məsələlərini əlavə etmək kimi bir şeyi avtomatlaşdırmaq lazımdırsa, nə etməli?

GitHub API lazımlı olduğu yerdir. GitHub-da veb saytında avtomatlaşdırılmış bir şəkildə edə biləcəyiniz hər şeyi etmək üçün çox sayda API nöqtəsi var. Bu bölmədə doğrulamağı və API-yə necə qoşulacağımızı, bir məsələyə necə şərh verəcəyinizi və API vasitəsilə Pull Request-in vəziyyətini necə dəyişdirəcəyinizi öyrənəcəyik.

Əsas İstifadə

Siz edə biləcəyiniz ən əsas şey doğrulama tələb etməyən endpoint-də sadə bir GET request-dir. Bu istifadəçi və ya açıq mənbəli bir layihədə yalnız oxu məlumatı ola bilər. Məsələn, “schacon” adlı bir istifadəçi haqqında daha çox bilmək istəyiriksə, belə bir şey işlədə bilərik:

$ 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"
}

Təşkilatlar, layihələr, məsələlər, commit-lər haqqında məlumat almaq üçün bu kimi endpoint-lər var - GitHub-da hər şey haqqında açıq şəkildə görə biləcəksiniz . Siz hətta ixtiyari Markdown göstərmək üçün API-dən istifadə edə və ya .gitignore şablonunu tapa bilərsiniz.

$ 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*
"
}

Bir Məsələyə Münasibət Bildirmək

Bununla birlikdə, bir Issue or Pull Request şərhini şərh etmək kimi bir veb saytında bir hərəkət etmək istəsəniz və ya şəxsi məzmuna baxmaq və ya qarşılıqlı əlaqə qurmaq istəyirsinizsə, identifikasiya lazımdır.

İdentifikasiyanın bir neçə yolu var. Əsas identifikasiyanı yalnız istifadəçi adınızı və şifrənizi istifadə edə bilərsiniz, ancaq ümumiyyətlə şəxsi giriş tokenindən istifadə etmək daha yaxşı bir fikirdir. Bunu parametrlər səhifənizdəki “Applications” bölməsindən əldə edə bilərsiniz.

Giriş Token
Figure 134. Parametrlər səhifənizdəki “Applications” bölməsindən giriş tokeninizi yaradın

Bu işarə və təsvir üçün hansı sahələri istədiyinizi soruşacaqdır. Skriptiniz və ya tətbiqiniz artıq istifadə edilmədiyi zaman token-i çıxartmağı rahat hiss etdiyiniz üçün yaxşı bir təsviri istifadə etdiyinizə əmin olun.

GitHub sizə bir token-i yalnız bir dəfə göstərəcəkdir, buna görə də onu kopyalayın. İndi istifadə edərək istifadəçi adı və şifrə istifadə etmək əvəzinə skriptinizdə identifikasiya etmək üçün istifadə edə bilərsiniz. Bu, çox xoşdur, çünki nə etmək istədiyinizi məhdudlaşdıra bilərsiniz və token-in ləğvi mümkündür.

Bu da dərəcəniz həddini artırmağın əlavə üstünlüyünə malikdir. Doğrulama olmadan, saatda 60 sorğu ilə məhdudlaşacaqsınız. Doğruladığınız təqdirdə saatda 5000 müraciət edə bilərsiniz.

Beləliklə, məsələlərimizdən birinə şərh etmək üçün istifadə edək. Deyək ki, 6-cı sayda müəyyən bir məsələyə münasibət bildirmək istəyirik. Bunu etmək üçün, yalnız Avtorizasiya başlığı olaraq hazırladığımız işarə ilə repos/<user>/<repo>/issues/<num>/comments-a bir HTTP POST tələb etməliyik.

$ 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:"
}

İndi bu məsələyə keçsəniz, yalnız GitHub API-dən bir şərh göndərildi -da uğurla yayımladığımızı görə bilərsiniz.

API Şərhi
Figure 135. GitHub API-dən bir şərh göndərildi

Veb saytından edə biləcəyiniz hər şeyi etmək üçün API-dən istifadə edə bilərsiniz - mərhələləri yaratmaq və təyin etmək, İnsanları Issues və Pull Requests-a təyin etmək, etiketlər yaratmaq və dəyişdirmək, commit məlumatlarına daxil olmaq, yeni commit-lər və branch-lar yaratmaq, açmaq, bağlamaq və ya etmək Pull Requests-in birləşməsi, qruplar yaratmaq və redaktə etmək, Pull Request-dəki kod sətirlərinə şərh vermək, saytı axtarmaq və s.

Pull Request Statusunun Dəyişdirilməsi

Pull Request-ləri ilə işləyirsinizsə, həqiqətən faydalı olduğundan baxacağımız bir son nümunə var. Hər bir commit-in onunla əlaqəli bir və ya daha çox statusu ola bilər və bu statusu əlavə etmək və soruşmaq üçün bir API var.

Davamlı İnteqrasiya və sınaq servislərinin əksəriyyəti bu API-dən istifadə edilən kodu sınamaqla push etməərə reaksiya vermək üçün istifadə edir və sonra bu commit-in bütün sınaqlardan keçdiyini geri bildirir. Əgər təqdimatçı bütün töhfələr qaydalarına əməl edirsə, commit düzgün imzalanıbsa, göndərmə mesajının düzgün formatlandığını yoxlamaq üçün istifadə edə bilərsiniz.

Deyək ki, əmanət mesajınızdakı Signed-off-by sətirini yoxlayan kiçik bir veb xidmətə xitabən depo qurduq.

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

Ümid edirik, bunu izləmək olduqca sadədir. Bu web hook işlədicisinə, sadəcə push etdikləri hər bir commit-ə baxırıq, commit mesajında Signed-off-by sətirini axtarırıq və nəhayət HTTP vasitəsilə /repos/<user>/<repo>/statuses/<commit_sha> vəziyyəti olan API endpointi tapırıq.

Bu halda bir vəziyyət (success, failure, error), baş verənlərin təsviri, istifadəçinin əlavə məlumat üçün gedə biləcəyi hədəf URL və bir commit üçün çox statuslu “context” göndərə bilərsiniz.. Məsələn, bir test servisi bir status təqdim edə bilər və bu kimi bir yoxlama servisi də bir status təqdim edə bilər - “context” sahəsi necə fərqləndiyini göstərir.

Kimsə GitHub-da yeni Pull Request açırsa və bu fork qurulubsa, API vasitəsilə Commit status kimi bir şey görə bilərsiniz.

Commit status
Figure 136. API vasitəsilə Commit status

İndi mesajdakı “Signed-off-by” sətri olan və yazarın imzalamağı unutduğu yerdən qırmızı xaç olan işarənin yanında bir az yaşıl bir işarə görə bilərsiniz. Ayrıca Pull Request branch-dakı son commitin vəziyyətini aldığını və uğursuz olduqda xəbərdarlıq etdiyini görə bilərsiniz. Bu API-ni test nəticələri üçün istifadə edirsinizsə, sonuncu commit-in uğursuz olduğu testləri təsadüfən birləşdirməməyiniz üçün çox faydalıdır.

Octokit

Bu nümunələrdə curl və sadə HTTP sorğuları ilə demək olar ki, hər şeyi etdiyimizə baxmayaraq bu API-ni daha idiomatik şəkildə təqdim edən bir neçə açıq mənbəli kitabxana mövcuddur. Bu yazı zamanı dəstəklənən dillərə Go, Objective-C, Ruby və .NET daxildir. Bunlar haqqında daha çox məlumat üçün https://github.com/octokitsəhifəsinə baxın, çünki sizin üçün HTTP-nin çox hissəsi idarə olunur.

Ümid edirik, bu vasitələr xüsusi iş axınlarınız üçün daha yaxşı işləmək üçün GitHub-u düzəltməyə və dəyişdirməyə kömək edə bilər. Bütün API sənədləri və ümumi tapşırıqlar üçün təlimatlar üçün https://developer.github.com səhifəsinə baxın.