GitHub Packages - CI/CD 구축 (Java + Gradle)

gzip·2023년 5월 29일
1

GitHub 찍먹

목록 보기
4/4
post-thumbnail

GitHub Packages를 이용해서 나의 패키지를 호스팅하고 GitHub Actions으로 CI/CD 구축하기


공식 문서의 설명이다. 보통 패키지 저장소들은 오픈소스를 올리는 것은 무료지만 개인 패키지는 유료 서비스를 이용하거나 따로 Repository Manager를 구축해야 한다.

GitHub Packages도 공개 패키지의 경우는 무료지만 비공개 패키지의 경우 무료 플랜은 500MB 제한이 있다. 여기에서 각 플랜 별로 제한을 확인할 수 있다.


Gradle 프로젝트 생성 및 설정

Gradle 프로젝트 생성

Gradle 7.6.1 버전으로 진행하였다.

$ mkdir ex-my-pk
$ cd ex-my-pk
$ gradle init

Select type of project to generate:
  1: basic
  2: application
  3: library
  4: Gradle plugin
Enter selection (default: basic) [1..4] 3

Select implementation language:
  1: C++
  2: Groovy
  3: Java
  4: Kotlin
  5: Scala
  6: Swift
Enter selection (default: Java) [1..6] 3

Select build script DSL:
  1: Groovy
  2: Kotlin
Enter selection (default: Groovy) [1..2] 2

Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no] no
Select test framework:
  1: JUnit 4
  2: TestNG
  3: Spock
  4: JUnit Jupiter
Enter selection (default: JUnit Jupiter) [1..4] 4

Project name (default: ex-my-pk):
Source package (default: ex.my.pk):

> Task :init
Get more help with your project: https://docs.gradle.org/7.6.1/samples/sample_building_java_libraries.html

BUILD SUCCESSFUL in 25s
2 actionable tasks: 2 executed

생성된 Gradle 프로젝트의 구조를 보자.

기본으로 lib라는 모듈에 Library라는 클래스가 하나가 생성되어 있고 someLibraryMethod()라는 메소드가 하나 있다.

빌드 후 성공하면 코드를 깃허브에 올려준다.


Gradle 프로젝트 설정

1. build.gradle.kts(root) 설정

루트에 build.gradle.kts 파일을 생성하고 아래와 같이 설정한다.

plugins {  
	`java-library`  
	`maven-publish`  
}  
  
subprojects {  
	apply(plugin = "java-library")  
	apply(plugin = "maven-publish")  
	  
	group = "ex.my.pk"  
	version = "1.0.0"  
	  
	configure<PublishingExtension> {  
		repositories {  
			maven {  
				name = "GitHubPackages"  
				url = uri("https://maven.pkg.github.com/hoho4190/ex-my-pk")  
				credentials {  
					username = project.findProperty("gpr.user") as String? ?: System.getenv("USERNAME")  
					password = project.findProperty("gpr.key") as String? ?: System.getenv("TOKEN")  
				}  
			}  
		}  
		publications {  
			register<MavenPublication>("gpr") {  
			from(components["java"])  
			}  
		}  
	}
    
    // jar task - manifest 파일에 라이브러리 이름과 버전을 포함  
    tasks.jar {  
        manifest {  
            attributes(mapOf("Implementation-Title" to project.name,  
            "Implementation-Version" to project.version))  
        }  
    }  
}

subprojectsgroup, version을 적어준다.

<dependency>
  <groupId>ex.my.pk</groupId>
  <artifactId>lib</artifactId>
  <version>1.0.0</version>
</dependency>

implementation("ex.my.pk:lib:1.0.0")

나중에 이런 식으로 디펜던시를 사용할 수 있다.

maven안에 urluri("https://maven.pkg.github.com/OWNER/REPOSITORY")처럼 깃허브 아이디와 리파지토리 이름을 적어주면 된다.

USERNAME, TOKEN은 환경 변수로 받을 것이다.

2. build.gradle.kts(lib) 설정

lib 모듈의 build.gradle.kts을 아래와 같이 설정한다.

repositories {  
	mavenCentral()  
}  
  
dependencies {  
	testImplementation("org.junit.jupiter:junit-jupiter:5.9.1")  
	   
	api("org.apache.commons:commons-math3:3.6.1")  
	  
	implementation("com.google.guava:guava:31.1-jre")  
}  
  
tasks.named<Test>("test") {  
	useJUnitPlatform()  
}
  
java {  
	withSourcesJar() // 소스 jar 생성  
	withJavadocJar() // API 문서 추가  
}
  • api: 이 디펜던시를 소비자에서 내보내진다. 즉, 컴파일 클래스 경로에서 찾을 수 있다.
  • implementation: 이 디펜던시는 내부적으로 사용되며 자체 컴파일 클래스 경로에서 소비자에게 노출되지 않는다.
  • apiimplementation의 자세한 설명은 문서 참고

빌드 후 성공하면 코드를 푸시하자.


GitHub Actions으로 CI/CD 구축

빌드 자동화

CI는 GitHub Actions - CI 구축 (Java + Gradle) 참고.


배포 자동화

Workflow 설정하기

깃허브 리파지토리의 Actions 탭에 들어가서 Publish Java Package with Gradle를 검색하고 Configure 클릭.

아래와 같이 설정한다.

name: Gradle Package

on:
  release:
    types: [created] # release가 생성될 때

jobs:
  build:
	
	# Workflow가 실행되는 vm의 OS 지정
    runs-on: ubuntu-latest
    
    # 권한
    permissions:
      contents: read
      packages: write

    steps:

	# 1. vm에서 리파지토리를 내려받음
    - uses: actions/checkout@v3

	# 2. vm에 jdk를 세팅함
    - name: Set up JDK 17
      uses: actions/setup-java@v3
      with:
        java-version: '17' # 버전
        distribution: 'temurin' # 배포판
        server-id: github 
        settings-path: ${{ github.workspace }}

	# 3. gradle build 실행
    - name: Build with Gradle
      uses: gradle/gradle-build-action@v2.4.2
      with:
        arguments: build

    # 4. gradle publish 실행
    # USERNAME, TOKEN 환경 변수에 추가
    - name: Publish to GitHub Packages
      uses: gradle/gradle-build-action@v2.4.2
      with:
        arguments: publish
      env:
        USERNAME: ${{ github.actor }}
        TOKEN: ${{ secrets.GITHUB_TOKEN }}

딱히 수정할게 없다. 자바 버전이랑 배포판을 맞게 적어주고 gradle-build-action 버전만 바꾸어 주면 된다. 현재 기준 v2.4.2가 최신이다.

이제 release를 하면 패키지가 자동으로 게시 된다. 확인해보자


Release 하기

우선 리파지토리를 보면 ReleasePackages가 없다.

Create a new release를 클릭하자.

tag는 gradle 프로젝트의 버전과 동일하게 v1.0.0으로 생성하고 제목과 내용을 적고 출시하자.


결과 확인하기

Actions 탭에 가서 보면 workflow가 실행되고 있을 것이다. 결과를 기다리자.

그리고 리포지토리의 Packages를 보면 자동으로 추가가 되어 있는 것을 확인할 수 있다.


사용해보기

깃허브 계정 > Settings > Developer settings > Personal access tokens > Tokens (classic)에서 개인 토큰을 생성하여 이용하여한다. 필요한 권한은 read:packages다.

위에서 만든 ex.my.pk를 사용할 프로젝트에서 아래처럼 설정하자.

repositories {  
	// ...
	maven {  
		url = uri("https://maven.pkg.github.com/hoho4190/ex-my-pk")  
		credentials {  
			username = System.getenv("USERNAME")  
			password = System.getenv("TOKEN")  
		}  
	}  
}


dependencies {  
	// ...
	implementation("ex.my.pk:lib:1.0.0")
}

IntelliJ build 설정에서 환경 변수에 USERNAME=xxx;TOKEN=xxx를 추가해준다.

혹은 명령어로

USERNAME=xxx TOKEN=xxx ./gradlew build

# USERNAME=xxx TOKEN=xxx ./gradlew build --refresh-dependencies

빌드 실행 후

다시 불러오면

ex.my.pk가 추가된 걸 확인할 수 있다. ex.my.pk에서 추가한 디펜던시들도 같이 추가된 것을 볼 수 있다.

이제 사용해보자.

api로 추가한 디펜던시는 사용자도 호출할 수 있지만, implementation로 추가한 디펜던시는 불가능하다.


개인 리포지토리의 패키지를 팀과 같이 사용하려면 리파지토리를 소유한 개인 또는 조직이 read:packages 권한이 있는 토큰을 공유해줘야 한다.

공개 리포지토리를 패키지를 다른 사람이 사용하려면 사용하려는 사람이 read:packages 권한이 있는 토큰을 만들어서 사용하면 되는거 같다. 공개 리포지토리는 토큰 없이 사용할 수 있을거 같지만 내가 못 찾은 건지 토큰 없이는 불가능한거 같다.


참고

0개의 댓글