GitHub 저장소와 연동해서 사용할 수 있는 CI 서비스로 대표적인 것이 TravisCI이다. 저장소에 커밋을 푸시하거나 Pull Request를 검증하기 위해서 코드를 linting하거나 테스트를 실행해 보는 것이 일반적이다. 이때 테스트를 수행하는 스크립트를 따로 만들어서 로컬에서는 ./test.sh
를 실행하고 TravisCI에서는 ./tavis.sh
를 실행하도록 설정하는 것도 가능하지만, 보통은 테스트 코드나 실행할 작업은 거의 같으면서 설정이나 초기화 작업 등만 다른 경우가 일반적이라서 별도로 관리하게 되면 불편한 점이 있다.
TravisCI의 환경변수로 TravisCI에서 실행되는지 검사하기
TravisCI에서는 TRAVIS
환경변수를 제공하므로 이 환경변수의 존재여부를 검사하면 같은 작업 내에서 TravisCI에서만 실행될 코드를 넣을 수 있다. TRAVIS
외에도 CI
, CONTINUOUS_INTEGRATION
환경변수도 제공하고 있으므로 원하는 것을 사용하면 된다. 예를 들어 gulp라면 다음과 같이 사용할 수 있다.
gulp.task('test', function (done) {
if (process.env.TRAVIS) { // 혹은 process.env.TRAVIS 나 process.env.CONTINUOUS_INTEGRATION
// Travis 전용 테스트 실행
} else {
// 로컬 전용 테스트 실행
}
});
bash
라면 다음과 같이 검사할 수 있다.
if [ "$TRAVIS" == "true" ]
then
echo "foo"
else
echo "bar"
fi
Pull Request의 테스트 검사하기
GitHub에서 TravisCI를 연동하면 저장소에 올라오는 Pull Request에 대해서도 테스트를 실행해서 다음과 같이 테스트 결과를 알려준다.
Travis에서 간단하게 테스트만 수행한다면 별다른 문제는 없지만 다른 서비스와 연동하면서 API 키를 사용하고 있다면 Pull Request에 대한 CI 테스트에서 문제가 발생한다. 테스트를 실행할 때 다른 서비스를 연동해야 한다면 보통 .travis.yml
파일에 API 키를 등록하게 되는데 이때 API키가 노출되면 안 되므로 TravisCI에서 제공하는 travis
CLI 도구를 사용해서 키를 암호화하게 된다. .travis.yml
은 GitHub 저장소에 공개적으로 올라가므로 API 키를 감추기 위해 암호화된 키를 등록하고 TravisCI에서 실행할 때 이 키를 복호화해서 사용하는 것이다. 그래서 키는 노출하지 않으면서 TravisCI에서 타 서비스를 사용할 수 있다.
테스트와 관련해서 사용해야 하는 서비스가 많지는 않지만, 대표적인 것이 브라우저 테스트를 수행하는 Sauce Labs이나 BrowserStack이다. 프로젝트에 크로스 브라우징 테스트가 필요한 경우 이러한 서비스를 연동해서 테스트를 수행하는데 작년에 summernote에 테스트를 추가하는 작업을 하다가 추가한 테스트가 Pull Request에서 실패하는 경험을 했다. 이 때문에 모든 Pull Request의 테스트가 실패하기 시작했는데 관련 이슈를 찾아보아도 처음에는 왜 실패하는지 잘 이해를 못 했다.
결론부터 얘기하자면 TravisCI에서 Pull Reqeust에 대해서는 암호화된 키를 복호화할 수 있는 키를 제공하지 않는다. 처음에는 TravisCI의 버그라고 생각했는데 관련 논의를 읽어보다 보니 이는 보안이슈 쪽에 더 가깝다. 테스트를 Sauce Labs에서 수행하도록 설정했으니 Pull Request의 테스트도 Sauce Labs에서 수행되는 것이 자연스러워 보이지만 Pull Request에 복호화키를 제공하는 경우 이를 통해서 연동서비스의 권한을 얻게 되므로 원하지 않는 동작은 수행하거나(혹은 의도적인 공격) 복호화키를 탈취하는 것이 가능하다. Pull Request에 올라온 코드는 검증된 코드가 아니므로 제공된 복호화키를 사용해서 원하는 작업을 무엇이든 실행할 수 있다. 이 때문에 TravisCI는 Pull Request에 대한 테스트에는 복호화키를 제공하지 않고 해당 이슈에서 보듯이 보안이슈 없이 이를 해결할 방법은 아직 못 찾은 것으로 보인다.
이 경우 Pull Request에서는 해당 테스트를 실행하지 않거나 API 키를 안전하게 제공할 방법이 있다면 해당 작업이 이뤄지도록 작업을 해야 한다. 이를 위해서 TravisCI에서는 Pull Request에서 실행되는 테스트에는 TRAVIS_PULL_REQUEST
라는 환경변수를 제공한다.
if [ "$TRAVIS_PULL_REQUEST" == "false" ]
then
# Pull Request가 아니면 테스트 실행
fi
이 환경변수를 통해서 위처럼 Pull Request가 아닌 경우에만 연동 서비스의 테스트를 실행할 수 있다.
Comments