[linux] curl과 jq를 이용한 github api 조회

개요

github rest API 문서를 보면 재미있는 API들이 있습니다.
오늘은 그 중 최신 release 가져오는 API를 만져보도록 하겠습니다.

준비물

jq

  • 설치 -> brew install jq

github access token

request

curl https://api.github.com/rate_limit

github API 분석

openjdk의 공급사인 adoptium의 최신 release를 가져오도록 하겠습니다.
github access token을 아래 넣어주고 API 요청을 합니다.

request

curl -L -H "Authorization: Bearer ${ACCESS_TOKEN}" \
https://api.github.com/repos/adoptium/temurin17-binaries/releases/latest

response

{
  "url": "https://api.github.com/repos/adoptium/temurin17-binaries/releases/119075034",
  "assets_url": "https://api.github.com/repos/adoptium/temurin17-binaries/releases/119075034/assets",
  "upload_url": "https://uploads.github.com/repos/adoptium/temurin17-binaries/releases/119075034/assets{?name,label}",
  "html_url": "https://github.com/adoptium/temurin17-binaries/releases/tag/jdk-17.0.8.1%2B1",
  "id": 119075034,
  "author": {
    "login": "eclipse-temurin-bot",
    "id": 81643974,
    "node_id": "MDQ6VXNlcjgxNjQzOTc0",
    "avatar_url": "https://avatars.githubusercontent.com/u/81643974?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/eclipse-temurin-bot",
    "html_url": "https://github.com/eclipse-temurin-bot",
    "followers_url": "https://api.github.com/users/eclipse-temurin-bot/followers",
    "following_url": "https://api.github.com/users/eclipse-temurin-bot/following{/other_user}",
    "gists_url": "https://api.github.com/users/eclipse-temurin-bot/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/eclipse-temurin-bot/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/eclipse-temurin-bot/subscriptions",
    "organizations_url": "https://api.github.com/users/eclipse-temurin-bot/orgs",
    "repos_url": "https://api.github.com/users/eclipse-temurin-bot/repos",
    "events_url": "https://api.github.com/users/eclipse-temurin-bot/events{/privacy}",
    "received_events_url": "https://api.github.com/users/eclipse-temurin-bot/received_events",
    "type": "User",
    "site_admin": false
  },
  "node_id": "RE_kwDOFjpjCs4HGPDa",
  "tag_name": "jdk-17.0.8.1+1",
  "target_commitish": "main",
  "name": "jdk-17.0.8.1+1",
  "draft": false,
  "prerelease": false,
  "created_at": "2022-08-15T07:03:39Z",
  "published_at": "2023-08-29T13:10:18Z",
  "assets": [
    {
      "url": "https://api.github.com/repos/adoptium/temurin17-binaries/releases/assets/123616608",
      "id": 123616608,
      "node_id": "RA_kwDOFjpjCs4HXj1g",
      "name": "OpenJDK17U-debugimage_aarch64_linux_hotspot_17.0.8.1_1.tar.gz",
      "label": "",
      "uploader": {
        "login": "eclipse-temurin-bot",
        "id": 81643974,
        "node_id": "MDQ6VXNlcjgxNjQzOTc0",
        "avatar_url": "https://avatars.githubusercontent.com/u/81643974?v=4",
        "gravatar_id": "",
        "url": "https://api.github.com/users/eclipse-temurin-bot",
        "html_url": "https://github.com/eclipse-temurin-bot",
        "followers_url": "https://api.github.com/users/eclipse-temurin-bot/followers",
        "following_url": "https://api.github.com/users/eclipse-temurin-bot/following{/other_user}",
        "gists_url": "https://api.github.com/users/eclipse-temurin-bot/gists{/gist_id}",
        "starred_url": "https://api.github.com/users/eclipse-temurin-bot/starred{/owner}{/repo}",
        "subscriptions_url": "https://api.github.com/users/eclipse-temurin-bot/subscriptions",
        "organizations_url": "https://api.github.com/users/eclipse-temurin-bot/orgs",
        "repos_url": "https://api.github.com/users/eclipse-temurin-bot/repos",
        "events_url": "https://api.github.com/users/eclipse-temurin-bot/events{/privacy}",
        "received_events_url": "https://api.github.com/users/eclipse-temurin-bot/received_events",
        "type": "User",
        "site_admin": false
      },
      "content_type": "application/x-compressed-tar",
      "state": "uploaded",
      "size": 162252748,
      "download_count": 493,
      "created_at": "2023-08-29T13:10:53Z",
      "updated_at": "2023-08-29T13:11:00Z",
      "browser_download_url": "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.8.1%2B1/OpenJDK17U-debugimage_aarch64_linux_hotspot_17.0.8.1_1.tar.gz"
    },
    ...
}

방대한 데이터가 오기 때문에 앞 부분만 잘랐습니다.
크게 부모 release object -> 자식 assets array 구조로 나눠져 있는 것을 볼 수 있습니다.
여기서 tag_name, assets[].browser_download_url 만 있으면 될 것 같네요.
하지만 tag_name은 부모, browser_download_url는 자식 array에 있으니 평탄화 해서 이쁘게 처리 해보겠습니다.

curl -L -H "Authorization: Bearer ${ACCESS_TOKEN}" \
https://api.github.com/repos/adoptium/temurin17-binaries/releases/latest |
jq '{("tag_name"): .tag_name, ("download_url"): .assets[].browser_download_url} |
select( .download_url | contains("jdk_x64_linux_hotspot")) |
select( .tag_name | contains("beta") | not) |
select( .download_url | test("\\.tar.gz$"))'

curl 이후 pipe를 통해 jq로 응답값을 전달합니다.
이제 본격적으로 jq를 이용해서 json을 만져볼텐데..
단락별로 나눠서 설명 드리도록 하겠습니다.

jq '{("tag_name"): .tag_name, ("download_url"): .assets[].browser_download_url}'

tag_name, assets[].browser_download_url를 파싱하여 한쌍의 json으로 노출될 수 있도록 평탄화해주는 작업을 합니다.
jq에서도 pipe를 통해 값을 이후로 전달할 수 있습니다!

select( .download_url | contains("jdk_x64_linux_hotspot")) |
select( .tag_name | contains("beta") | not) |
select( .download_url | test("\\.tar.gz$"))

jq select 함수를 이용하여 필터링 합니다. 여기서 필터링할 내용이 몇가지 있는데

  • linux x64 hotspot
  • beta 제외
  • tar.gz로 끝나는 확장자

이 3가지 유형을 contains, not contains, 정규식등의 예제가 각각 보여줍니다. 이제 결과물을 보자면?

{
  "tag_name": "jdk-17.0.8.1+1",
  "download_url": "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.8.1%2B1/OpenJDK17U-jdk_x64_linux_hotspot_17.0.8.1_1.tar.gz"
}

우리가 원하는 데이터가 나옵니다. 이런 방식으로 github API를 응용하면 재미난 것을 많이 구현할 수 있습니다.

linux bash shell script jq github latest release

2023

[linux] shell script version compare

최대 1 분 소요

개요 linux를 사용하다 보면 version 비교하는 기능이 필요합니다. 특히 기존 설치된 패키지의 version을 확인하여 업데이트할 경우가 있겠죠. 아래와 같이 간단한 shell script로 구현할 수 있습니다.

[jenkins] jenkins docker install

2 분 소요

ci/cd 오픈소스 도구로 가장 많이 사랑 받는 jenkins에 대해 포스팅 해보겠습니다. 먼저 설치부터 해야겠지요? 항상 패키지 매니저로 설치했었는데 이번에는 docker로 설치해보도록 하겠습니다.

[springboot] springboot history

2 분 소요

springboot 탄생 배경 springboot란 spring framework를 좀 더 쉽게 개발/배포할려는 목적으로 만들어 졌습니다. 2012년 Mike Youngstrom은 spring 프레임워크에서 컨테이너 없는 웹 애플리케이션 아키텍처에 대한 지원을 요청하는 spring...

[springboot] springboot3 querydsl 적용

1 분 소요

개요 springboot3로 메이저 업그레이드 되면서 JPA + querydsl 셋팅 환경에 변화가 생겼습니다. 기존 의존성으로는 작동하지 않고 jakarta classification을 추가해야 작동하는 이슈가 발생합니다. springboot3부터 javax -> jakar...

[springboot] springboot3 migration

최대 1 분 소요

개요 2022년 하반기에 springboot3가 공식 release 되었습니다. springboot2가 2018년 상반기에 release되고 나서 새롭게 판올림 버전으로 가장 큰 변화로는 아래와 같습니다. spring framework 6 적용 최소 사양 JDK 17 ...

[springboot] springboot initializer

최대 1 분 소요

개요 항상 intellij ultimate 버전만 사용하고 있었는데 무슨 바람이 난건지.. intellij ce 버전에 도전하였습니다. springboot 프로젝트 생성이며.. 그 밖에 기본적으로 될꺼라 싶은것 중에 안되는 녀석들도 꽤 있더군요. 이번 시간엔 간단하게 spingbo...

[querydsl] querydsl No release for a long time

최대 1 분 소요

개요 JPA를 spring data jpa + querydsl과의 조합으로 접하는 경우가 많습니다. spring data jpa에서 제공해주는 specification으로도 충분히 해낼수 있지만 querydsl에 비할바는 아닙니다. entity에 wrapper Q클래스를 생성하여 ...

[jekyll] jekyll install

6 분 소요

개요 오랫동안 방치했던 블로그를 다시 열면서 jekyll를 다시 설치해봤습니다. 설치 jekyll 프로젝트로 이동하여 아래 명령어를 입력합니다. gem install jekyll bundler Fetching pathutil-0.16.2.gem Fetching terminal-t...

맨 위로 이동 ↑

2021

[linux] Parse yaml

최대 1 분 소요

bash를 사용하여 yaml 파일을 파싱 및 환경 변수로 손쉽게 등록할 수 있습니다.

[유틸리티] Mock Http Status Test

최대 1 분 소요

외부 통신에 대한 Error 처리는 앱을 더욱 더 견고하게 만들 수 있습니다. Error 처리를 위해 엔드포인트에 대한 Http Status Code를 억지로 생성하는것은 매우 귀찮은 일이라고 할까요? 보다 간편하게 Mock 서버를 두는게 더 효율적이라고 볼 수 있습니다.

맨 위로 이동 ↑