Uknow's Lab.
article thumbnail

 

 

Github Actions

Github Actions란, Github에서 제공하는 DevOps, CI/CD (지속적 통합/지속적 배포) 도구입니다.

Github Actions를 사용하여 Github 저장소의 빌드, 테스트, 배포 등을 자동으로 하는 도구입니다.

 

여러 Workflow를 자동화하고, 다양한 이벤트 트리거에 따라 작업을 처리할 수 있습니다.

 

 

커밋이 될 때 혹은 develop branch와 main branch가 병합될 때, 자동으로 테스트 코드를 행하여,

테스트 코드가 성공한다면 배포를 한다거나,

특정 주기마다 스크립트를 실행하는 상황에 쓰이곤 하는데,

 

저는 이번엔 커밋이 될 때 마다 README.md를 업데이트 하는 용도로 써보겠습니다.

 

 

 

Github Action 권한 설정

 

 

[Github 레포지토리] -> [Settings] 탭 -> [Actions] -> [General]로 들어가,

위와 같이 Read and write permissions를 선택합니다.

 

이제 workflow에서 읽기 뿐만 아니라 쓰기도 가능하게 되었습니다.

 

 

 

파일 입출력으로 README.md 생성하기

 

[Kotlin]

import java.io.File
import java.text.SimpleDateFormat
import java.util.Calendar

fun main() {
    val githubBasePath = "/home/runner/work/{저장소 이름}/{저장소 이름}"
    val readMe = File("$githubBasePath/README.md")

    val content = StringBuilder()

    content.appendLine(readMe.readText()) // 기존 내용을 그대로 가져옴


    val now = Calendar.getInstance().apply {
        add(Calendar.HOUR, 9) // UTC +9 (한국 시각으로 변경)
    }

    val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") // 날짜 포맷

    content.appendLine("updated at ${simpleDateFormat.format(now.timeInMillis)} - GitHub Actions") // 내용 추가

    readMe.writeText(content.toString()) // 파일에 내용을 씀
}

 

 

 

[Java]

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class Main {
    public static void main(String[] args) throws IOException {
        String githubBasePath = "/home/runner/work/{저장소 이름}/{저장소 이름}";
        File readMe = new File(githubBasePath + "/README.md");

        StringBuilder content = new StringBuilder();


		// BufferedReader로 파일 내용 읽기
        BufferedReader reader = new BufferedReader(new FileReader(readMe));
        String line;

        while ((line = reader.readLine()) != null) {
            content.append(line).append("\n");
        }

        reader.close();

		// 현재 날짜와 시간 받아오기(Github 서버는 세계 표준시이므로, +9시간 하여 한국 시간에 맞춤)
        Calendar now = Calendar.getInstance();
        now.add(Calendar.HOUR, 9);

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 날짜 포맷
		
        // 업데이트 로그 작성하기
        content.append("updated at ${simpleDateFormat.format(now.timeInMillis)} - GitHub Actions"); // 내용 추가

		
        // 파일에 쓰기
        BufferedWriter writer = new BufferedWriter(new FileWriter(readMe));
        writer.write(content.toString());
        writer.close();
    }
}

 

 

저는 코틀린이 가장 편해서 코틀린으로 해당 코드를 작성하였는데요.

아직까진 코틀린보다는 자바가 편하신 분들이 많을 것 같아 자바로 작성한 파일 입출력 코드도 첨부하였습니다.

 

README.md의 내용을 그대로 읽고, 업데이트 되었다는 문구룰 추가하여 다시 README.md에 쓰는 코드이며,

파일 입출력을 사용한 기초적인 읽기, 쓰기이기 때문에 코드에 관한 설명은 주석으로 대체하겠습니다.

 

 

여기서 한 가지 주의깊게 보실 점은,

String githubBasePath = "/home/runner/work/{저장소 이름}/{저장소 이름}";

저장소 이름 부분에 자신의 저장소 이름을 작성하면 됩니다.

 

만약, README.md 파일이 없다면 오류가 발생할 수 있으니, README.md 파일을 만들어주세요.

빈 파일이여도 됩니다.

 

 

 

Github Actions 스크립트 작성 [yml]

 

 

이제 Github Actions 스크립트를 작성할 단계입니다.

위와 같이 레포지토리에서 Actions 탭을 누르면

기본 workflow와 여러 템플릿 workflow들이 보입니다.

템플릿 workflow를 사용하면 쉽고 빠르게 workflow를 작성할 수 있습니다.

 

저는 가장 기본 형태인 Simple workflow를 선택하였습니다.

 

 

 

이제 여기에 Github Actions 스크립트를 작성하면 됩니다.

 

 

 

name: Run Kotlin and Commit Changes

on:
  push:
    branches:
      - main

jobs:
  build_and_test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up JDK
        uses: actions/setup-java@v2
        with:
          java-version: '11' # 필요한 Java 버전을 지정
          distribution: 'adopt' # 배포판을 선택

      - name: Build with Gradle
        run: |
          # 권한 설정
          chmod +x github-action-test-helper/gradlew
          
          # 폴더 이동
          cd github-action-test-helper/src/main/kotlin
          
          # Main.kt 파일 빌드 후 실행
          kotlinc Main.kt -include-runtime -d Main.jar
          java -jar Main.jar
      
      - name: Git Config
        run: |
          # Git 설정
          git config user.name "깃허브 유저 네임 입력"
          git config user.email "깃허브 유저 이메일 입력"
      
      - name: Git commit and push
        run: |
          # 파일을 커밋하고 푸시
          git add .
          git commit -m "커밋명 입력"
          git push origin main

 

 

저는 위와 같이 작성해주었는데요.

제일 위의 name은 해당 workflow의 이름입니다.

 

on은 이벤트 트리거를 설정하는 부분으로써, 저는 main branch에 push가 될 때를 트리거로 지정하였습니다.

 jobs는 작업을 수행하는 부분입니다. 저는 build_and_test라는 작업을 수행하도록 하였습니다.

steps는 말 그대로 작업의 스텝입니다. 각 스텝은 순차적으로 이루어집니다.

저는 Checkout Code -> JDK 설치 -> Gradle로 자바 빌드 및 실행 -> Git 설정 -> Git commit & push로 구성하였습니다.

 

 

이제 다 끝났습니다.

커밋을 할 때마다 README.md가 업데이트 되는지 확인할 차례입니다!

 

 

 

commit & push 트리거 발생 -> README.md를 업데이트!

 

 

이벤트 트리거인 push가 될 때 마다, workflow가 작동하는 모습입니다.

초기엔 경로 지정이나 스크립트 작성에 오류가 있어 실패한 모습이 보이네요.

 

 

 

 

테스트용으로 커밋을 몇 번 해봤는데,

커밋 & 푸쉬 마다 README.md가 업데이트 되는 모습을 볼 수 있었습니다.

우여곡절이 많았지만 잘 작동하는 모습을 보니 보기 좋군요...

 

 

자세한 레포지토리 구조와 코드는 아래 Github Repository에서 확인하실 수 있습니다.

https://github.com/yoon6763/github-action-test-lab

 

GitHub - yoon6763/github-action-test-lab: Github Action 실험실

Github Action 실험실. Contribute to yoon6763/github-action-test-lab development by creating an account on GitHub.

github.com

 

 

 

후기

1일 1코딩테스트를 진행하고 있는데,

READMD.md에 풀었던 문제들을 정리해놓으면 보기 좋지 않을까? 하는 생각에,

코틀린과 파일 입출력을 사용해 저장소 내 소스코드와 문제 정보를 긁어와

README.md에 출력해주는 자동 생성기를 만들었습니다.

 

그러나, 매번 실행하기가 귀찮아 Github에 commit & push가 될 때마다,

README.md를 생성하는 코틀린 파일이 자동으로 실행될 순 없나? 라는 생각에

DevOps, CI/CD 도구인 Github Actions가 떠올라 만지작 거렸는데,

우여곡절 끝에 README.md 업데이트 자동화에 성공하긴 했네요.

profile

Uknow's Lab.

@유노 Uknow

인생은 Byte와 Double 사이 Char다. 아무말이나 해봤습니다.