github apiを使用する

a white dice with a black github logo on it github

またしてもAPIのお話

React nativeプロジェクトで使用しているライブラリでバージョンごとに非推奨になっていたり、使うべきではないものが含まれているか、または現在使用しているバージョンの前後にもそのようなものがあるか調べる必要があった。


本来は、ReactNativeアプリでめんどくさいことは、AndroidとiOSのバージョンやXcodeのバージョンの差による違いでうまく行かないことだらけだろうから、それはまた次回。

手段としては、githubAPIで各ライブラリのリポジトリのrelease noteをチェックし、非推奨の文字列が含まれるバージョンを抜き出し、まとめてEXCELにする。


そのEXCELのリンクをまた文字解析をして、非推奨になった呼び出しや処理を抜き出し、現在のコードに存在しないかチェックする。(これはこの記事の対象外)

手順としては
tokenの作成
リクエストテスト
プログラムの作成
実行
の流れ

※tokenの作成時にこの記事ではpersonal access token (classic) の作成をしているが、
ビジネスなどで使用する場合はclassicでないものを作成すべきです

tokenの作成

公式ページに書いてあるとおり、

アカウントページの【settings】→一番下の【Developper Settings】→【Personal access tokens】と進み
【Tokens(classic)】を選択後、右上にある【Generate new token】を押下する

現在はgithubは2段階認証が必須だった気がするので認証を行い、必要なテキストボックスを埋めていく

Select scopesでは、読みのみなので以下を選択した。

repo
public_repo
read:repo_hook
read:user
user:email

Generate Tokenボタンで作成完了。
tokenはコピーし、無くさないように保持する

リクエストテスト

pythonでリクエストテストを行う

今回行いたいのはリリース情報ページを取得し、そこに非推奨になったり削除されたものがあるかを調べたいので

ドキュメントによるとエンドポイントは以下になる

/repos/{owner}/{repo}/releases

テスト対象はreact-native

{
    "react-native": {
        "OWNER": "facebook",
        "REPO": "react-native"
    }

とりあえず100件取得する

headers = {
        'Authorization': f'token {TOKEN}',
        'Accept': 'application/vnd.github.v3+json'
    }
url = f'https://api.github.com/repos/{OWNER}/{REPO}/releases?per_page=100'
response = requests.get(url, headers=headers)
response.ok # エラーなら認証等見直し
releases = response.json()

うまく取得できていそうだ

プログラムの作成

今回情報が欲しいライブラリはたくさんあるが一部抜粋

github_repos = {
    "react-native": {
        "OWNER": "facebook",
        "REPO": "react-native",
        "version":"0.69.3"
    },
    "@react-native-async-storage/async-storage": {
        "OWNER": "react-native-async-storage",
        "REPO": "async-storage",
        "version":"1.17.7"
    },
    "@react-navigation/native": {
        "OWNER": "react-navigation",
        "REPO": "react-navigation",
        "version":"6.0.11"
    },
## 略
}

関数を作成

テストと異なる点は、100件を3ページ取得することとbody(コメント)を見て、非推奨に該当しそうな文字列が含まれるもののみをreturn するという点

import requests
from time import sleep

def get_repo_and_deprecated_note(OWNER, REPO, TOKEN):
    headers = {
        'Authorization': f'token {TOKEN}',
        'Accept': 'application/vnd.github.v3+json'
    }

    url = f'https://api.github.com/repos/{OWNER}/{REPO}/releases?per_page=100'
    max_pages = 3  # 最大ページ数
    current_page = 0  # 現在のページ数

    keywords = ['deprecate', 'deprecated', 'obsolete', 'removed', 'no longer supported', 
                'discontinued', 'sunsetted', 'legacy']
    
    results = []

    while url and current_page < max_pages:
        print(url)
        response = requests.get(url, headers=headers)
        sleep(2)
        releases = response.json()
        if not isinstance(releases, list): 
            break

        for release in releases:
            body = release.get('body', '') 
            if body is None:
                continue
            for keyword in keywords:
                if keyword in body.lower():
                    results.append(f"Version: {release['tag_name']} - {release['html_url']}")
                    break 


        link_header = response.headers.get('Link', '')
        next_link = [link for link in link_header.split(',') if 'rel="next"' in link]
        
        if next_link:
            url = next_link[0].split(';')[0].strip().strip('<>')
        else:
            url = None

        current_page += 1

    return results

そしてgithub_reposをループして
取得したデータをDataFrameに変えてエクセル出力。

API取得は以上。
このあとの言語処理がうまく行かず結局数件ずつだが目で見る羽目に。。。

終わりに

github APIは今回使用したが、個人としてはあまり使うことは少なそうかなぁ?

push等もIDEに組み込まれてることがほとんどだし、何か便利機能があるのか調べておきます

タイトルとURLをコピーしました