GitLab でソースコードのバージョン管理を行っている。
プロジェクトでは、多数のリポジトリを管理することになる。
その中で、各リポジトリの設定ファイル(gradle.properties)の特定の値をすべて取得する必要があった。
シェルスクリプトで GitLab の API と通信し、リポジトリ ID、リポジトリ名、収集したいプロパティを一覧化して取得する。
今回収集したいプロパティは gradle.properties に記載されている値で、以下、『PROP』と呼ぶ。
前提
jq コマンドのインストール
公式に記載のある方法で、jqコマンドをインストールする。
Windowsなので、今回はwingetを使用する。
winget install jqlang.jq
GitLab の API を使用するために、一時キーを取得する。
※ ここで発行するトークンがあれば社内プロジェクトにアクセスできてしまうため、取り扱いには注意すること。
設定画面から新しいトークンを発行する。
GitLab の UI > サイドバー上部にある自身のアイコン > Edit Profile
> Access Tokens > Add new token
権限は以下を選択する。
- api
- read_api
プログラム
GITLAB_URL="https://xxx.com/gitlab" # xxx はプロジェクトで使用している GitLab の URL
TOKEN="XXXXX" # 先ほど取得したトークン(※ このプログラムを配布するなら直書きは NG)
GROUP_ID=XX # 後述①
# グループ内のプロジェクト ID 一覧を API で取得(後述②)
curl --silent --header "PRIVATE-TOKEN: $TOKEN" \
"$GITLAB_URL/api/v4/groups/$GROUP_ID/projects?per_page=100&include_subgroups=true" |
jq '.[] | select(.archived == false) | .id' > projects.txt
dos2unix projects.txt # 改行コードを LF に統一
while read id; do
# プロジェクト情報を API で取得(後述③)
name=$(curl --silent --header "PRIVATE-TOKEN: $TOKEN" \
"$GITLAB_URL/api/v4/projects/$id" | jq -r '.name')
# gradle.properties の情報を取得(後述④)
content=$(curl --silent --header "PRIVATE-TOKEN: $TOKEN" \
"$GITLAB_URL/api/v4/projects/$id/repository/files/gradle.properties/raw?ref=master")
# PROP 行を抽出
prop=$(echo "$content" | grep -E '^PROP.+$')
if [ -z "$prop" ]; then # prop が存在しなければ none とする
prop="none"
fi
echo "REPO_ID: $id, REPO_NAME: $name, PROP: $prop" # 取得結果をコンソールに出力する
done < projects.txt # 先ほど出力したプロジェクト ID 一覧を記載したテキストを読み込む
echo "done"
dos2unix projects.txt # 改行コードを LF に統一
改行コードが間違っていると、変数が正しく展開されず、うまくいくはずのAPI通信でエラーが発生したりする。
ファイル出力を伴う場合は、上記コードを忘れずに記述すること。
①の解説
GROUP_ID=XX
グループ ID は、GitLab で対象のグループを選択し、以下のページで確認できる。
Settings > General
②の解説
curl --silent --header "PRIVATE-TOKEN: $TOKEN" \ "$GITLAB_URL/api/v4/groups/$GROUP_ID/projects?per_page=100&include_subgroups=true" | jq '.[] | select(.archived == false) | .id' > projects.txt
グループ内で作成されているアクティブなリポジトリのプロジェクト ID を一覧化し、ファイルに保存する。
以下、詳細。
curl --silent --header "PRIVATE-TOKEN: $TOKEN" \
curl で GitLab に通信を送る
$GITLAB_URL/api/v4/groups/$GROUP_ID/projects?
グループ ID をキーにプロジェクト情報を取得する(GitLab API仕様)
per_page=100&include_subgroups=true
100 リポジトリ(最大)まで取得する
グループ配下のサブグループも対象とする
jq '.[] | select(.archived == false) | .id' > projects.txt
アーカイブされているリポジトリは除外する
ID を projects.txt に保存する
③の解説
name=$(curl --silent --header "PRIVATE-TOKEN: $TOKEN" \
"$GITLAB_URL/api/v4/projects/$id" | jq -r '.name')
プロジェクトidをキーにプロジェクト情報のリストを取得し、jqでプロジェクト名を取り出す。
以下、詳細。
name=$(curl --silent --header "PRIVATE-TOKEN: $TOKEN" \
curl で GitLab API と通信する
"$GITLAB_URL/api/v4/projects/$id"
先ほど取得したプロジェクト ID をキーに、プロジェクト情報を取得する
jq -r '.name'
取得したプロジェクト情報からプロジェクト名を抽出する
name=
変数nameにプロジェクト名を格納する
④の解説
content=$(curl --silent --header "PRIVATE-TOKEN: $TOKEN" \
"$GITLAB_URL/api/v4/projects/$id/repository/files/gradle.properties/raw?ref=master")
プロジェクトidをキーにリポジトリのコンテンツを取得し、gradle.propertiesのローデータを取得する
content=$(curl --silent --header "PRIVATE-TOKEN: $TOKEN" \
curl で GitLab API と通信する
"$GITLAB_URL/api/v4/projects/$id/repository/files/gradle.properties/raw?ref=master")
先ほど取得したプロジェクト ID をキーに、特定のファイル(ここでは gradle.properties)の内容を取得する
GitLab の API 仕様に基づき、ファイルを raw 形式で取得している
Appendix
GUI でプロジェクト ID からアクセス
https://xxx.com/gitlab/projects/<PROJECT_ID>
インシデント
変数が正しく展開されない
projects.txt に以下が記載されている。
58
59
69
これを取り出してループ処理したいが、変数が正しく展開されない。
while read id; do
echo "ID is: [$id]"
done < projects.txt
以下のように、変数展開がおかしくなる。
ID is: [58
原因は、projects.txt の改行コードが CRLF になっているため。
事前に以下のコマンドで改行コードを書き換えてからループ処理に渡す。
dos2unix projects.txt

コメント