Tech story/Cloud

gRPC 라이브러리 배포 및 문서 자동화 프로세스 수립

kt cloud 테크블로그 2024. 11. 11. 16:02

[kt cloud 플랫폼Innovation팀 강솔 님]

 

gRPC 라이브러리 배포 및 문서 자동화 프로세스 수립

 

gRPC 기반 시스템에서는 서비스와 메시지가 개발 과정에서 자주 변화합니다. 이때 변경된 API 문서를 최신화하는 작업은 필수적이지만 반복 작업으로 인해 자동화가 필요합니다. 이번 글에서는 gRPC 서비스의 .proto 파일이 변경될 때마다 문서를 자동으로 생성하고 이를 별도 GitHub repository에 배포 및 관리하는 방법을 소개합니다.

 

 

1. 자동화 프로세스 정의하기

 

1.1. 자동화 목표 수준 정의

자동화 프로세스는 다음의 목표를 달성하고자 합니다.

 

1. 자동화 목표

  1. 라이브러리 자동 배포: .proto 파일이 변경될 때마다 라이브러리가 자동으로 업데이트됩니다.
  2. 문서 자동 생성: .proto 파일이 변경될 때마다 최신 문서가 자동으로 생성됩니다.
  3. 문서 저장 및 관리: 생성된 문서를 별도의 Git Repository에 저장하여 관리합니다.

이를 위해 protoc-gen-doc 플러그인과 GitHub Actions를 사용해 .proto 파일이 변경되면 문서를 생성하고 라이브러리와 문서를 자동 배포하도록 프로세스를 설계했습니다.

 


2. 자동화 프로세스 수립

  1. [local] Git Commit & Push
  2. [Github] Actions 수행
    1. 소스 빌드
    2. 라이브러리 배포
    3. 문서 생성 및 저장소에 업데이트

 

 

 

2. Gradle 빌드 설정

 

2.1. 플러그인 추가하기

자동화된 문서 생성과 배포를 위해 protoc-gen-doc 플러그인과 maven-publish 플러그인을 Gradle에 추가합니다.

plugins {
    id 'java'
    id 'com.google.protobuf' version '0.9.4'
    id 'maven-publish'
}
group = 'cohttp://m.ktcloud.next.sample.grpc.network'
version = '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
ext {
    grpcVersion = '1.58.0'
    protobufVersion = '4.28.0'
    protocGenDocVersion = '1.5.1'
}
dependencies {
    implementation "io.grpc:grpc-protobuf:${grpcVersion}"
    implementation "io.grpc:grpc-stub:${grpcVersion}"
    implementation "com.google.protobuf:protobuf-java:${protobufVersion}"
    implementation 'javax.annotation:javax.annotation-api:1.3.2'
}

 

2.2. 문서 생성 작업 정의하기

.proto 파일에서 정의한 내용을 Markdown 및 AsciiDocs 포맷으로 변환하는 작업을 설정합니다. 여러 타입의 API 문서를 생성하기 위해 개별 task를 정의하고 빌드 시 실행될 수 있도록 generateAllDocs task를 정의합니다.

// build.gradle
task generateSubnetDocs(type: Exec) {
    commandLine 'protoc',
            '--doc_out=./out',
            '--proto_path=src/main/proto',
            '--doc_opt=template/grpc-md.tmpl,subnet-api-doc.md',
            'src/main/proto/com/ktcloud/next/sample/network/subnet/services/*.proto',
            'src/main/proto/com/ktcloud/next/sample/network/subnet/requests/*.proto',
            'src/main/proto/com/ktcloud/next/sample/network/subnet/responses/*.proto',
            'src/main/proto/com/ktcloud/next/sample/network/subnet/messages/*.proto'
}
task generatePortDocs(type: Exec) {
    commandLine 'protoc',
            '--doc_out=./out',
            '--proto_path=src/main/proto',
            '--doc_opt=template/grpc-asciidoc.tmpl,port-api-doc.adoc',
            'src/main/proto/com/ktcloud/next/sample/network/port/services/*.proto',
            'src/main/proto/com/ktcloud/next/sample/network/port/requests/*.proto',
            'src/main/proto/com/ktcloud/next/sample/network/port/responses/*.proto',
            'src/main/proto/com/ktcloud/next/sample/network/port/messages/*.proto'
}
task generateAllDocs {
    dependsOn generateSubnetDocs, generatePortDocs
}
build.dependsOn generateAllDocs

 

3. GitHub Actions

 

 

이제 Github Actions를 통해 .proto 파일이 변경될 때마다 라이브러리와 문서가 자동으로 배포되도록 설정합니다.

3.1. 워크플로우 기본 설정

1. 워크플로우 트리거 조건 설정

     1. main 브랜치로 푸시될 때마다 워크플로우가 실행됩니다.

name: Gradle Package
on:
  push:
    branches: ['main']
 
 

2. 작업 환경 설정

   a. Ubuntu 환경에서 실행되며, repository 내 코드 및 파일에 대한 read 권한과 packages 배포 권한을 부여합니다.

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

 

3.2. 작업 정의하기

1. 코드 체크아웃 및 환경 설정

    1. 작업이 수행될 환경에 대한 설정입니다. 개별 프로젝트에 맞는 설정을 입력합니다.

steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
  uses: actions/setup-java@v4
  with:
    java-version: '21'
    distribution: 'temurin'
- name: Setup Gradle
  uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582

 

2.Github 패키지 자격증명 설정

  1. Github에서 발급된 토큰정보를 Action을 수행할 Repository에 등록하는 절차가 필요합니다.
    1. repository > Settings > Secrets and Variables > Actions > Repository secrets에 필요한 정보를 저장합니다(내부 정책 따름).
    2. Repository secrets에서 등록된 정보를 기반으로 Acitons 내 Crendentials 정보를 추가합니다.
- name: Set up GitHub Packages Credentials
  run: |
    echo "githubRefPackagesUsername=${{ secrets.PACKAGES_USERNAME }}" >> ~/.gradle/gradle.properties
    echo "githubRefPackagesPassword=${{ secrets.PACKAGES_PASSWORD }}" >> ~/.gradle/gradle.properties

 

3. 빌드 및 배포 수행

    1.  프로젝트를 빌드하고, 빌드된 라이브러릴 Github Packages에 배포합니다.

- name: Build with Gradle
  run: ./gradlew build
- name: Publish to GitHub Packages
  run: ./gradlew publish
  env:
    USERNAME: ${{ github.actor }}
    TOKEN: ${{ secrets.PACKAGES_PASSWORD }}

 

4.Document Repository로 문서 배포

  1. Document를 별도 관리할 Repository를 Github에서 먼저 생성합니다.
  2. Actions가 수행되는 프로젝트에서 생성된 API 문서를 해당 Repository로 복제합니다.
- name: Checkout Document Repository
  uses: actions/checkout@v4
  with:
    repository: kt-cloud-api-iam/next-sample-grpc-document
    token: ${{ secrets.PACKAGES_PASSWORD }}
    path: ./grpc-document-repo
- name: Copy generated files to Document Repository
  run: |
    rm -rf ./grpc-document-repo/${{ github.repository }}
    mkdir -p ./grpc-document-repo/${{ github.repository }}
    cp -r ./out/* ./grpc-document-repo/${{ github.repository }}
- name: Commit and Push to Document Repository
  run: |
    cd grpc-document-repo
    git config user.name "github-actions[bot]"
    git config user.email "github-actions[bot]@users.noreply.github.com"
    git add .
    if git diff --cached --quiet; then
      echo "No changes to commit"
    else
      git commit -m "Add generated documentation files"
      git push origin main
    fi

 

5. 생성 결과 확인

 

    1. 라이브러리 배포 확인


    2. 문서 배포 확인