규도자 개발 블로그

github actions로 자동 1일 1커밋 봇 만들기 본문

DevOps/Git

github actions로 자동 1일 1커밋 봇 만들기

규도자 (gyudoza) 2022. 4. 12. 21:01

github actions로 자동 1일 1커밋 봇 만들기

그냥 재미있는 생각이 들었다. 1일 1커밋을 생활화하려는 개발자들이 있지만 그게 또 힘드니 이걸 github actions로 해결하면어떨까(?)하는 그런 생각 말이다.

 

알다시피 github actions에는 PR이나 push등의 이벤트에만 작동하는 것이 아닌, 일정 시간마다 작동하는 workflow또한 작성할 수 있다. 진짜 간단한 scheduled.yml을 작성해보자. 아, 모든 과정은 내가 인프라 공부할 때 사용하는 https://github.com/jujumilk3/infra-study 이 레포지토리에서 진행할 것이니 행여 나중에 진행과정을 참고할 사람이 있다면 해당 저장소의 커밋 내역을 따라가보면 될 것이다. 그리고 Actions칸에 있는 수많은 실패내역도 그대로 둘 터이니 반면교사로 참고할 사람은 참고하면 될 것이다.

# scheduled.yml
name: Scheduled Jobs

on:
  schedule:
    - cron: '5/* * * * *'

jobs:
  print:
    runs-on: ubuntu-latest

    steps:
      - name: say hello
        run: echo "Hello world"

맨 처음에 이렇게 작성해봤는데 5/* 라는 시간세팅이 먹히질 않는다. 제목은 크론이면서 크론식 문법을 완전히 지원하는 것 같진 않다. 아무튼 수정해서

name: Scheduled Jobs

on:
  schedule:
    - cron: '20 * * * *'

jobs:
  print:
    runs-on: ubuntu-latest

    steps:
      - name: say hello
        run: echo "Hello world"

해봤는데 20분이 돼도 또 안된다. 안내를 읽어보니 매시간 작동되는 스케쥴잡은 딜레이가 있을 수 있다고 한다...(https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule) 인내를 갖고 기다려보면

이렇게 실행된 걸 확인해볼 수 있다. 확인해보니 내가 설정해놓은 스케쥴보다 10분 후에 작동됐으니 작동이 안된다고 새로 스케쥴을 써서 마구마구 커밋하지 말자. 그럼 계속 밀린다. 이걸 어떻게 아느냐? 나도 알고 싶지 않았다 ㅠ... 아 그리고 참고로 시간설정은 UTC를 기준으로 해서 돌아가니 유의하자.

 

 

시간설정은 완료됐으니 이제 git repository를 받아서 수정하고 다시 push하는 workflow만 짜면 된다.

name: Scheduled Jobs

on:
  schedule:
    - cron: '0 0 * * *'

jobs:
  test_schedule:
    runs-on: ubuntu-latest
    steps:
      - name: Hello World
        run: echo "Hello World"

      - name: repository checkout
        uses: actions/checkout@v2
        with:
          repository: jujumilk3/infra-study
          token: ${{ secrets.MY_GITHUB_TOKEN }}
          path: infra-study

      - name: Add date and push
        run: |
          cd infra-study
          date >> date.txt
          git add .
          git config --global user.email "github-actions@github.com"
          git config --global user.name "github-actions"
          git commit -am "Inject Date"
          git push

이렇게 짜봤다. 흐름을 직관적으로 파악할 수 있다. 이 repository를 checkout해서 date를 입력하고 다시 push하는 과정이 써있다.

 

여기에서 주목해야할 부분은 respository checkout단계에 있는 actions/checkout@v2${{ secrets.MY_GITHUB_TOKEN }}이다.

 

actions/checkout@v2앞에 있는 uses라는 명령어의 의미는 깃허브 혹은 사용자들이 작성해놓은 패키지를 이용한다는 의미이다. actions/checkout@v2의 저장소는 https://github.com/actions/checkout이곳이며 간단하게 어떻게 사용하고 어떻게 작동하는지 확인할 수 있다. 눈치가 빠른 사람들은 알겠지만 {{user_id}}/{{project_name}}@{{version}}형태로 구성돼있다. 이밖에도 github marketplace/actions에 가보면 많은 사람들이 작성해둔 패키지들을 찾아볼 수 있다. 용도와 취향에 맞게 골라서 사용하면 된다.

 

두번째로 ${{ secrets.MY_GITHUB_TOKEN }}은 저장소에 push하기 위한 작업이다. 자신의 github를 컨트롤하기 위한 token은 https://github.com/settings/tokens 이곳에서 발급받을 수 있는데 이 토큰을 prject -> setting -> secrets -> Actions에 등록하는 것이다.

이런식으로 자신이 Actions에 사용할 것이지만 외부에 노출되면 안되는 민감한 정보들을 저장해둘 수 있다. 근데 왜 굳이 MY_라는 접두어를 붙였냐, GITHUB_로 시작하는 secret은 등록되지가 않는다. 아마 GITHUB_로 시작되는 환경변수는 githubActions자체에서 예약어로 사용하고 있는데 그게 덮어씌워져서 github actions가 작동되지 않는 불상사를 방지하기 위해서 사용하지 못하게 한 게 아닌가 하는 생각이다.

 

 

 

자, 이렇게 1일 1커밋 봇을 완성하였다. 이 포스팅을 하면서 재미있는 일이 있었는데 schedule로 걸어두고 기다리는 게 귀찮아서 그냥 push이벤트에 wf를 걸어놨더니

 

yml파일을 수정하고 main에 push -> github actions가 실행되어 date를 써서 main에 push-> github actions가 실행되어 date를 써서 main에 push-> github actions가 실행되어 date를 써서 main에 push-> ...

 

순식간에

이만큼의 action이 일어났다. 이 광기는 -f push로 잠재웠다. 테스트할 때 주의하자.

 

추가로 내가 위에 작성해둔 yml파일은 내 계정명과 repository name이 하드코딩돼있는데 이걸 자신에게 맞게 변경해도 되지만(진짜로 활용할 사람이 있다고 믿진 않겠다) github actions에서 제공하는 변수를 이용하면 간단하게 자신의 계정명과 repository를 가져와서 step들을 진행시킬 수 있다.

name: Scheduled Jobs

on:
  schedule:
    - cron: '0 0 * * *'

jobs:
  test_schedule:
    runs-on: ubuntu-latest
    steps:
      - name: echo repository name
        run: echo "${{ github.repository }}"

      - name: repository checkout
        uses: actions/checkout@v2
        with:
          repository: ${{ github.repository }}
          token: ${{ secrets.MY_GITHUB_TOKEN }}
          path: infra-study

      - name: Add date and push
        run: |
          cd infra-study
          date >> date.txt
          git add .
          git config --global user.email "github-actions@github.com"
          git config --global user.name "github-actions"
          git commit -am "Inject Date"
          git push

하드코딩돼있던 저장소이름을 github actions에서 제공하는 변수로 변경하였다. 이 wf만 아무 github 저장소에 추가하면 당신도 눈이오나 비가오나 1일 1커밋하는 개발자가 될 수 있다. 추가로 밑에서 이제일주소와 사용자이름을 설정하는 부분도 자신의 github 계정으로 변경해야만 이 wf가 진행하는 commit이 자신의 잔디밭에 적용된다.

 

 

사실은 그냥 뭔가 억지로 하는 1일 1커밋이나 봇이 하는 거나 무슨 차이가 있나 싶어서 해학적으로 풀어보고 싶었다.

 

 

 

아 그리고 추가로 github actions의 귀여운 점이 있다. 바로 secrets에 추가한 값이 노출되면 ***로 처리한다는 점이다. 만약에 actions secret에

이런식으로 secret을 추가한 뒤에 secret에 적혀있는 데이터를 사용해보려고 하면

이렇게 ***로 가려주니까 screts로 등록된 값들에 대한 노출에 대해서 그렇게 걱정하지 않아도 된다. 해당 부분은 wf에

    - name: echo shy var
      run : echo "${{ secrets.TEST_SECRET }}"

이렇게 선언돼있다. secrets를 이용해 API_KEY나 API_SECRET_KEY가 주소에 들어간 요청을 보내야 하는데 어떡하나 걱정할 필요가 없다. actions에서 이미 다 처리해서 가려주기 때문이다.

 

정말 귀여운 어플리케이션이다.

 

 

Comments