Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

DevYGwan

Jitpack & github releases를 사용한 라이브러리 배포 본문

Study/DEVELOP

Jitpack & github releases를 사용한 라이브러리 배포

YGwan 2024. 9. 13. 15:43

 회사에서 flyway을 도입하려 했는데 저희가 사용하는 DB가 flyway를 지원하지 않는 문제를 발견했습니다. 해당 공식 Repository에서 지원하는 DB 목록을 볼 수 있습니다. (https://github.com/flyway/flyway) 따라서 이 문제를 해결하기 위해 flyway 지원 코드를 작성했고 테스트를 완료했습니다. 이에 대한 설명은 다음 장에서 설명드리도록 하겠습니다.

 그렇게 해서 flyway 지원을 성공적으로 했고, 공식 레포에 문의하여 PR을 통해 지원할 수 있게끔 요청을 남겼습니다. 하지만 문제가 PR이 언제 될지 모르고, 응답도 빨리 오지 않아 당장 사용하기가 힘들었습니다. 그래서 이 문제를 해결하기 위해

 

"우리가 작성한 코드를 라이브러리로 배포해보자"

 

 라는 생각이 들었습니다. 우리가 배포한다면, flyway 공식 Repository에서 승인하지 않더라도 다른 프로젝트에서 쉽게 라이브러리 추가가 가능하기 때문에 유용하게 사용할 수 있을 것이라고 생각했습니다. 따라서 라이브러리 배포하는 방법을 찾아봤습니다. 생각보다 많은 방법이 있는 것을 알게 되었습니다. 크게 라이브러리를 배포할 수 있는 방법은

  1. MvnRepository을 통한 라이브러리 배포
  2. Github releases & packages를 활용한 라이브러리 배포
  3. Github releases & jitpack을 활용한 라이브러리 배포

 이렇게 3가지가 있었습니다. 이를 간단하게 설명하고 제가 어떤 방식을 선택했는지 & 처리하면서 어떤 이슈가 있었는지를 설명하도록 하겠습니다.

 

1.  MvnRepository을 통한 라이브러리 배포

 MvnRepository는 실제 프로젝트를 해본 사람이라면 익숙한 사이트일 것이라고 생각합니다. 이 사이트를 간단하게 설명하자면, Maven 중앙 저장소(Maven Central Repository)와 관련된 메타데이터를 검색하고 제공하는 웹 사이트입니다. Maven 중앙 저장소는 Maven 프로젝트의 종속성을 관리하는 데 사용되는 가장 널리 사용되는 저장소 중 하나입니다. Gradle은 Maven 중앙 저장소에서 의존성을 가져오기 때문에, Maven 의존성 정보를 Gradle의 build.gradle 파일에 적용할 수 있습니다.

 따라서 처음에는 MvnRepostiory에 배포하는 방식으로 라이브러리를 배포하려고 했습니다. 하지만, GPG 서명처리, Sonatype에서 배포 승인 절차 진행 등 과정이 번거롭고 시간이 오래 걸려 단순히 간편하게 쓰려는 목적과는 맞지 않았습니다. 해당 방법은 아래 링크에 절차가 잘 나와있으니 아래 링크를 참고해주시면 얼마나 번거로운지 알 수 있으실 겁니다...

 

2. Github  packages를 통한 라이브러리 배포

 GitHub Packages는 GitHub의 패키지 관리 서비스로, 소프트웨어 패키지를 저장하고 배포할 수 있는 기능을 제공합니다. 이를 통해 개발자들은 자신이 만든 라이브러리나 애플리케이션을 다른 개발자와 쉽게 공유할 수 있습니다. 주요 특징으로는,

  1. 다양한 패키지 형식 지원:
    • Docker, npm, Maven, RubyGems 등 여러 형식의 패키지를 지원합니다.
  2. 통합된 생태계:
    • GitHub의 다른 기능(예: GitHub Actions, GitHub Releases)과 통합되어, CI/CD 파이프라인에서 패키지를 쉽게 관리하고 배포할 수 있습니다.
  3. 버전 관리:
    • 패키지의 버전을 관리하고, 이전 버전으로 롤백할 수 있는 기능을 제공합니다.
  4. 접근 제어:
    • 패키지에 대한 접근 권한을 설정할 수 있어, 공개 또는 비공개로 배포할 수 있습니다.
  5. 사용자 인증:
    • GitHub의 사용자 인증 시스템을 통해 안전하게 패키지를 관리할 수 있습니다. (Github Token 사용)

 저같은 경우 SpringBoot를 사용한 코드를 배포하려고 하기 때문에 mvn & gradle 패키지 클라이언트를 사용하면 됩니다. 하지만 Github Packages의 경우 제대로 배포가 완료되어 Packages에 업로드가 되었는대도 불구하고 의존성 추가시 경로를 못찾는 경우가 있었습니다. 하지만 에러 로그를 확인할 수 있는 방법이 없었고, setting.xml & pom.xml에 이를 위한 추가적인 코드를 작성해야 하기 때문에 기존 코드의 변경점이 생긴다는 단점이 있었습니다. 따라서 이 방법 대신 마지막 3번째 방법을 선택했습니다. Github Packages를 활용한 배포 방법에 대한 자세한 설명도 아래에 좋은 글이 있어 공유드리겠습니다.

 

 

3. Github Releases & jitpack를 활용한 배포

 Github Releases는 특정 커밋을 기반으로 소프트웨어 버전을 관리하고 배포하는 기능입니다. Github Repository의 우측 하단에 보면, Releases를 설정할 수 있는 부분이 있습니다. 해당 부분을 클릭하면, 버전을 태깅하여 소프트웨어 버전을 관리할 수 있고 릴리즈에 대한 설명 & 변경사항을 기록할 수 있습니다. (업데이트 할때마다 쌓인다.) 또한, 추가적인 파일 첨부가 가능하여 사용자들이 쉽게 필요한 파일들을 다운 받을 수 있습니다.

 Jitpack은 Github에서 호스팅된 Java 프로젝트를 쉽게 배포하고 사용할 수 있도록 도와주는 서비스입니다. Maven & Gradle을 지원하고 Gihub의 Releases를 기반으로 자동으로 빌드를 수행합니다. 기본적으로는 무료지만, private Repository를 배포할 경우 유료 버전으로만 가능합니다.(https://jitpack.io/private#subscribe)

 따라서, Github Releases & Jitpack을 활용한 방법은 Github 프로젝트의 Releases 파일이 업데이트 될 경우 Jitpack에서 자동으로 코드를 읽어 배포를 수행해줍니다. 이때, 배포를 위해 추가적으로 환경 설정을 해야할 경우 Jitpack.yml 파일을 추가하면 jitpack에서 이를 읽어 배포 전 환경을 설정하고 배포를 진행합니다. 주의할 점은 Release 파일이 업로드 되는 시점에 배포가 되는 것이 아니고 jitpack에서 해당 파일을 읽어 배포가 끝난 시점에서야 실제 배포가 완료되 사용이 가능하다는 점 입니다. 하지만 실제로 시간 간격이 길지 않아 큰 문제가 되진 않다고 생각했습니다. ( 대략 1 ~ 2분 소요 )

 

이렇게 라이브러리 배포를 위한 다양한 방법이 존재합니다. 저는 이 중 기존 코드의 변경점이 제일 적고 쉽고 빠르게 배포를 할 수 있는 Github Releases & jitpack를 활용한 배포 방식을 선택했습니다. github Releases를 통해 라이브러리 사용 시 필요한 추가적인 파일을 업로드 할 수 있고 설명도 추가할 수 있어 저희한테 맞는 배포 방식이라고 생각했기 때문입니다. 또한 개인적으로는 배포 로그를 확인할 수 있어 에러가 발생했을 때, 어디서 에러가 발생했는지를 바로 확인할 수 있다는 장점이 좋았고 실제 공식적으로 운영하는 DOCS도 잘 나와 있어 사용하기 편리했습니다.

 

그렇다면, Github Releases & jitpack를 활용한 배포를 어떻게 하는지 간단하게 설명드리도록 하겠습니다.

 


※  Github Releases & jitpack를 활용한 배포 방법

 

1. Github Releases 추가

 라이브러리로 배포할 프로젝트의 Repository에서 Github Releases를 추가합니다. Github Repository의 우측 하단의 Releases 버튼을 누르고, Draft a new release 버튼을 클릭합니다. 이후 적절한 태그와 타겟 브랜치를 선택하고, 설명을 추가한 후 publish release 버튼을 클릭하여 배포를 수행합니다. 수행이 끝나면 아래와 같이 release가 추가된 것을 확인할 수 있습니다.

 

2. jitpack 웹사이트 이동

 https://jitpack.io/ 사이트로 이동합니다. 이동 후, 사용자 이름/저장소를 입력하고 내가 설정한 태그의 파일이 업로드 된 것을 확인할 수 있습니다. "사용자명/저장소" 를 입력하고 Look up을 클릭하면 아래와 같이 제대로 업로드가 되는 것을 확인할 수 있습니다. 만약 보이지 않는다면, jitpack이 아직 읽지 못한 것이기 때문에 새로고침을 해보면 금방 보이는 것을 확인할 수 있을 것입니다. 

 

3. Log로 설정된 파일을 읽어 SUCCESS 확인

 처음에는 저 Log에 표시가 아무것도 되어 있지 않을 것입니다. 하지만 시간이 지나면 로딩되는 것을 확인할 수 있으며, 로딩이 끝나면 파일 표시로 되어 클릭하면 배포 로그를 확인할 수 있습니다. 배포 로그를 클릭하고 제대로 success가 됐는지를 확인합니다. 제대로 완료가 됐다면 배포가 완료가 된 것입니다. 만약 실패했다면, 에러 로그를 확인하여 수정한 후 다시 첫번째부터의 과정을 반복합니다.

 

4. 사용 방법 확인

 배포가 완료되면 "사용자명/저장소" 를 입력한 페이지 하단에 보이는 사용방법을 확인하여 라이브러리를 사용합니다. 아래의 사진과 같이 특정 상황에 맞는 사용 방법이 제시되어 있습니다. 따라서 제가 배포한 라이브러리를 사용하려는 프로젝트에서 해당 코드를 추가하면, 편리하게 라이브러리를 간편하게 사용할 수 있습니다.

  • 주의할 점 : Gradle에서 사용시 사용자명:Repository 주소 형식으로 의존성을 추가하는 것으로 확인되는데 사용자명.Repository 방식으로 해야 의존성이 제대로 추가가 됩니다.

 

5.  다른 프로젝트에서 의존성 추가 후, 제대로 의존성이 추가 됐는지 확인하기

 위의 방법을 활용하여 다른 프로젝트에서 의존성을 추가한 후 External Libraries에서 해당 의존성이 제대로 추가되었는지를 확인합니다. 확인 결과 나의 github 주소에 내가 작성한 코드의 jar 파일이 제대로 추가가 된 것을 확인할 수 있었습니다.

 

 이렇게 전 Github Releases & jitpack을 활용하여 라이브러리 배포를 진행했습니다. 아래부터는 제가 배포를 진행하면서 겪은 이슈들과 해결방법을 소개하면서, Github actions를 통해 release 생성 과정을 자동화하는 방법을 설명드리겠습니다.

 


※  Github Releases & jitpack 배포 과정시 겪은 문제

 

1. Java 버전 확인

 저희 프로젝트는 Java 17 버전을 사용하여 코드를 작성했습니다. 그런데 아래 사진과 같이 jitpack에서는 기본적으로 Java 8 버전을 사용해서 빌드 환경을 구성합니다. 이로 인해 버전 문제가 발생했습니다. 제가 겪은 문제는 lombok 문제였는데, 자바 8 버전과 자바 17버전이 사용하는 lombok이 달라서 생기는 문제였습니다.(https://github.com/awhitford/lombok.maven/issues/179)

Jitpack build Log를 살펴 본 결과 생긴 에러 로그

 

 따라서 jitpack 공식 문서를 확인해본 결과, jitpack.yml 파일을 생성하여 프로젝트의 root 경로에 추가하면 jitpack이 배포 시 해당 파일을 읽어 환경 설정을 해주는 것을 확인했습니다. 따라서 저 같은 경우 Java 17을 사용하기 때문에  openjdk17를 추가하여 문제를 해결했습니다. 아래의 왼쪽 사진은 jitpack 공식 문서에 나와 있는 자바 버전 관련 내용이고, 오른쪽 사진은 jitpack.yml 파일을 추가하여 jdk 버전을 명시했을 때, Jitpack 배포 시 나오는 로그 내용입니다. 보시는 바와 같이 jdk17 버전을 다운 받아 환경 설정 하는 것을 확인할 수 있습니다.

 

2. Github Release Tag 네이밍

 저는 Release의 TAG를 네이밍 할때, flyway의 버전인 10.16.0 버전에 저희의 버전을 합쳐 10.16.0.{our_version} 이런 식으로 명시하려고 했습니다. 하지만 이렇게 명시하니 문제가 생겼습니다. 제대로 될 때도 있었지만 내가 원하는 시점의 commit을 기준으로 release가 생기지 않는다던가, jitpack으로 배포 시 제대로 배포가 되지 않는 문제가 종종 발생했습니다. 확인 결과 version 생성 시에 기본적인 규칙이 존재하는 것을 알 수 있었습니다. "Semantic Versioning" 방식으로 버전을 관리합니다. 해당 방식을 간단하게 설명하자면, 버전을 "MAJOR.MINOR.PATCH" 의 3가지 부분을 기준으로 관리하는 것입니다. 따라서 저도 처음에는 4가지 부분으로 버전을 관리하려 했지만 3가지 부분으로 버전을 관리하니 제대로 처리가 되는 것을 확인할 수 있었습니다.

 

3. 멀티 모듈 처리

 저의 팀의 프로젝트는 멀티 모듈로 이루어져 있습니다. 따라서 의존성 추가시 제가 원하는 모듈의 의존성을 명시해줘야 합니다. 해당 방법을 확인해보니, Jitpack 공식 문서에 잘 나와 있었습니다. 의존성 추가 시 내가 원하는 모듈을 명시하여 의존성을 추가한다면, 내가 원하는 모듈의 의존성을 추가 할 수 있습니다.

https://docs.jitpack.io/building/#multi-module-projects

 

 위의 이슈 이외에는 기본적으로 빠르고 쉽게 라이브러리를 배포할 수 있는 방법이기 때문에 크게 문제될 것은 없었습니다.

 


※  Github Actions를 통한 CI/CD 적용

 코드가 업로드가 되면 github Release 매번 업데이트 해야합니다. Github Release 업데이트 방법은

Github Repository 이동 -> Release 페이지 이동 -> Draft a new release 버튼 클릭
-> 버전(Tag) 지정 -> Release 제목 및 설명 추가 -> Release 생성

 절차를 통해 업데이트가 됩니다. 하지만 매번 코드 변경이 생길때마다 이러한 작업을 매번 사람이 반복하는게 힘들 수 있습니다. 따라서 저희는 이를 Github Actions를 통해 자동화했습니다. 기본적인 github actions 코드는 create-release 공식 repository에서 설명한 코드를 기반으로 작성했습니다. (https://github.com/actions/create-release

 

name: Release New Version

on:
  pull_request:
    branches:
      - main
    types: [ closed ]

jobs:
  release-new-version:
    name: Release-new-version
    runs-on: ubuntu-latest
    permissions:
      packages: write
      contents: write
      id-token: write

    if: github.event.pull_request.merged == true && startsWith(github.head_ref, 'release/') && contains(github.head_ref, '.')
    steps:
      - uses: actions/checkout@v4

      - name: Get branch name
        run: echo "TAG=$(echo '${{ github.head_ref }}' | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')" >> $GITHUB_ENV

      - name: Create a GitHub release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ env.TAG }}
          release_name: ${{ env.TAG }}
          # body: |
          #   Changes in this Release
          #   - First Change
          #   - Second Change
          draft: false
          prerelease: false

  Github Actions 코드 및 설명을 간단하게 설명하자면,

  • Main 브랜치에 머지 시에 Github Actions이 동작합니다.
  • Release 생성 시 권한 설정을 위한 Permissions을 추가했습니다.
  • branch명이 release/ 로 시작하고, . 을 가지고 있는 브랜치가 머지되었을 때 정의한 job들이 실행됩니다.
  • branch 명은 버전 명을 나타내며, 브랜치 명의 숫자를 .을 기준으로 3개로 분리해 이를 release의 tag & title 값으로 설정합니다.
  • draft와 prerelease는 false로 설정합니다. (공식 create-release 기준)

 

 Main 코드에 변경 사항이 발생하면, 사람이 직접 release를 업데이트하는 대신, Github Actions가 이벤트를 감지해 자동으로 처리되도록 로직을 구현했습니다. Release가 업데이트되면 Jitpack에서 이를 감지하여 배포를 진행함으로써 버전 업데이트를 유연하게 처리할 수 있도록 했습니다.

 


※  정리

 여태까지 나만의 라이브러리를 만들 수 있는 3가지 방법을 비교하고 그 중 제가 선택한 Github Releases & jitpack 방식의 사용 방법과 이슈들을 정리했습니다. 단순히 개발하는 것 뿐만아니라 어떻게 하면 더 쉽게 사용할 수 있을지를 고민하여 개발 이외의 것을 고민할 수 있는 기회가 된 것 같아 좋았습니다. 끝으로 같이 참여해주신 팀원분들께 감사드립니다!!