Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

Travis CI 빌드에서 Github에 릴리즈 하기

Github에는 프로젝트의 릴리즈를 관리하는 기능이 있다. Github에 소스를 푸시할 때 태그를 올리면 저장소의 Releases 메뉴에 자동으로 등록이 돼서 모아볼 수 있다. jQuery처럼 태그는 사용하지만 릴리즈 기능을 따로 사용하지 않고 있는 프로젝트도 있고 Bootstrap이나 lodash처럼 Github의 릴리즈 기능을 이용해서 버전 별 릴리즈노트를 작성하고 공지에도 활용하는 경우도 있다.

Github에서 릴리즈를 추가하는 화면

프로젝트 전용 사이트가 있는 경우에는 사이트나 블로그를 통해서 릴리즈 공지를 하지만 그렇게 큰 프로젝트가 아니라면 Github의 릴리즈 기능을 사용하면 편하다. 태그를 푸시하고 Release 메뉴에서 Draft a new release를 누르면 위처럼 릴리즈 노트를 작성할 수 있다. 버전을 명시하고 변경사항이나 공지할 내용을 작성하면 프로젝트 이용자가 새 버전에서의 변경 점을 쉽게 파악할 수 있어서 유용하다. 내가 관리하는 프로젝트에서는 별도로 사이트를 관리하기는 번거로우므로 이 기능을 적극적으로 사용하고 있다. 얼마 전 다른 일로 이 릴리즈 기능을 자동화하려는 시도를 해보았다. 릴리즈 노트 같은 경우는 어차피 손수 적어줄 수밖에 없지만, 배포가 그냥 소스배포가 아니라(해당 태그의 소스코드는 자동으로 등록된다.) 빌드과정 후 결과물을 배포해야 한다면 매번 릴리즈에 빌드해서 릴리즈에 업로드하는 것은 귀찮은 일이다.

오픈 소스에서는 보통 Travis CI를 사용하고 있는데 Travis CI에서 Github Release 기능을 지원하고 있어서 Github 릴리즈를 어느 정도 자동화할 수 있다. Travis CI를 이미 사용하고 있다면 테스트나 빌드 성공 여부를 검사하고 있을 것이고 프로젝트에 .trvias.yml파일 등록되어 있을 것이다.

deploy:
  provider: releases
  api_key: "GITHUB OAUTH TOKEN"
  file: "FILE TO UPLOAD"
  skip_cleanup: true
  on:
    tags: true

Travis CI에서 빌드나 테스트 성공 후 Github에 릴리즈하려면 위와 같은 코드를 추가해야 한다. 위 코드는 Github Release API를 사용해서 특정 파일을 업로드 하도록 하는 설정이고 API를 사용해야 하므로 Github의 Oauth token이 필요하다.(public_reporepo의 권한이 필요하다.) 하지만 private 저장소를 쓰는 게 아니라면 공개된 저장소에 Github 인증토큰을 그대로 올릴 수는 없다.(물론 토큰 권한을 저 권한만 주면 제어는 할 수 있다.)

그래서 Travis CI의 CLI 도구에서 자동 설정 기능을 포함해서 인증키를 암호화하는 기능을 제공하고 있다.

$ travis setup releases
Username: outsideris
Password for outsideris: ****
Two-factor authentication code for outsideris: 
File to Upload: dist-file
Deploy only from summernote/angular-summernote? |yes|
Encrypt API key? |yes|

travis cli를 설치한 뒤 위처럼 travis setup releases를 실행하면 Github 인증 후에 프로젝트에 릴리즈 설정을 추가하게 된다. 업로드할 파일이라 배포 설정도 나오는데 이는 나중에 수정하면 되니까 크게 중요치 않고 Encrypt API key를 하면 인증 토큰을 암호화해서 파일에 추가하게 된다.

deploy:
  provider: releases
  api_key:
    secure: D7QkXMGWdGdZ4JlgNq8qlakwOuNitZvIY3qTsoDb3xuObCwaySUASXu2+N0wLnAaMKQKONDpFSqANwuGPiad/Ws5scuajrySIaTCMDBkSNz6igmO5vwEuLHcvRGIEnzEMhIDDFs1hxeoQf+5D6nuFsaVny09JVw6vp8ybJVTc48=
  file: dist-file
  on:
    repo: summernote/angular-summernote

이를 실행하면 .travis.yml에 위와 같은 코드가 추가된다. 토큰은 미리 받아놓지 않더라도 다음과 같이 자동으로 토큰을 발급받아서 암호화하므로 크게 신경 쓰지 않아도 된다. API 키는 암호화된 토큰이므로 공개된 Github 저장소에 그대로 올려도 상관없다.

Github에 자동으로 등록된 인증 토큰

before_deploy: "grunt deploy"
deploy:
  provider: releases
  api_key:
    secure: D7QkXMGWdGdZ4JlgNq8qlakwOuNitZvIY3qTsoDb3xuObCwaySUASXu2+N0wLnAaMKQKONDpFSqANwuGPiad/Ws5scuajrySIaTCMDBkSNz6igmO5vwEuLHcvRGIEnzEMhIDDFs1hxeoQf+5D6nuFsaVny09JVw6vp8ybJVTc48=
  file:
    - "dist/angular-summernote.js"
    - "dist/angular-summernote.min.js"
  skip_cleanup: true
  on:
    tags: true
    all_branches: true
    repo: summernote/angular-summernote

before_deploy는 배포 실행 전에 실행할 명령인데 여기서는 grunt deploy라고 적었지만, 자신의 프로젝트에서 빌드하는 명령어를 여기에 적으면 된다. 이 과정이 오류 없이 진행된다면 deploy 과정이 진행되고 여러 파일을 업로드 해야 한다면 file에서 지정하면 된다. on부분은 deploy가 실행되는 조건에 대한 부분이다. tags: true로 설정하면 해당 빌드에 태그가 추가되었을 때만 배포가 진행되고 Travis CI의 이슈때문에 이 기능은 전체 브랜치로 지정했을 때만 사용할 수 있다. 그래서 태그를 키면 브랜치 지정하는 부분은 꺼야 한다. all_branches: true 부분을 지정해야 하고 .travis.ymlbranches: 부분으로 특정 브랜치를 지정하고 있다면 이 부분을 제거해야 정상적으로 동작한다.

이 설정을 완료한 후에 소스를 푸시할 때 릴리즈를 위해서 태그를 추가해서 푸시하면 아래와 같이 Travis에서 빌드 후 배포를 진행하게 된다.

Travis CI에서 빌드 후 deploy가 진행된 로그

Github의 릴리즈 메뉴에 가보면 해당 파일이 등록되어 있고(소스파일은 자동으로 등록된다.) 해당 릴리즈가 pre-release로 등록된 것을 볼 수 있다.

2015/03/25 03:10 2015/03/25 03:10