Jenkins GIT_COMMIT — Git 플러그인의 덮어쓰기
Jenkins 파이프라인 하나가 앱을 빌드해 이미지를 올리고, 그다음 배포 매니페스트를 갱신하고, 이때 레포를 두 개 썼습니다. 파이프라인 스크립트가 든 레포는 Job SCM 으로 걸어 두니 Jenkins 가 워크스페이스에 알아서 체크아웃해 주고, 실제 빌드 대상인 앱 레포는 파이프라인 안에서 스크립트가 직접 클론하는 구조였습니다.
매니페스트에는 앱 레포의 커밋 해시를 박아 두고, 지금 떠 있는 게 앱의 어느 커밋인지 나중에 되짚으려는 것이라 여기 들어가는 값이 Job SCM 쪽 해시면 아무 쓸모가 없습니다.
env.GIT_COMMIT = sh(script: 'git -C app rev-parse HEAD', returnStdout: true).trim()
그런데 배포 매니페스트엔 매번 jenkinsfile 레포의 해시가 찍혀서, 제가 넣은 값이 어딘가에서 사라지고 있었습니다.
원인 — Git 플러그인의 GIT_COMMIT 재주입
Git 플러그인은 GIT_COMMIT, GIT_BRANCH, GIT_URL 을 EnvironmentContributor 로 등록하고, 이
셋은 환경 변수를 읽을 때마다 Job SCM 기준으로 다시 계산돼 주입됩니다.
스크립트에서 env.GIT_COMMIT = ... 로 대입해도 나중에 그 값을 읽는 시점에 플러그인이 Job SCM,
그러니까 jenkinsfile 레포의 해시로 다시 덮어씁니다. 대입은 성공하지만 읽기에서 지는 겁니다.
이걸 확신한 건 매니페스트의 git-commit 이 매 빌드마다 jenkinsfile 레포의 HEAD 와 정확히
일치했기 때문입니다.
#23 → edc3784 (jenkinsfile 레포 HEAD)
#24 → 3a83a9c (jenkinsfile 레포 HEAD)
앱 레포에서 그 해시를 찾으면 없는 커밋이었습니다.
git -C app cat-file -e edc3784 # → 존재하지 않음
앱 레포에 없는 해시를 앱 배포에 쓰고 있었다는 뜻이고, 그러면 남는 건 그 값이 어디서 왔는지입니다.
해결 — withEnv 블록으로 스코프 제한
전역 env 에 대입하는 대신 그 값을 쓰는 step 을 withEnv 블록으로 감쌌습니다. 블록 스코프
안에서는 대입한 값이 플러그인이 채우는 값보다 우선합니다.
def appCommit = sh(script: 'git -C app rev-parse HEAD', returnStdout: true).trim()
withEnv(["GIT_COMMIT=${appCommit}"]) {
// 여기서 GIT_COMMIT은 앱 레포 해시
sh 'render-manifest.sh'
}
withEnv 블록 안에서만 GIT_COMMIT 이 앱 레포 해시로 덮이고, 블록을 벗어나면 플러그인이 넣어
둔 값으로 돌아가는 상태가 됩니다.
플러그인이 관리하는 변수와 withEnv 스코프
env.X = ... 대입이 안 먹히면 그 변수를 플러그인이 관리하는지부터 의심하면 됩니다. Git
플러그인의 GIT_COMMIT 처럼 EnvironmentContributor 로 주입되는 값은 읽을 때마다 재계산돼서
스크립트 대입을 무시하고, Job SCM 과 빌드 대상이 다른 파이프라인에서 특히 헷갈립니다. 플러그인이
채우는 값은 Job SCM 기준이기 때문입니다.
그런 값은 전역에 대입하려 하지 말고 withEnv 로 쓸 구간만 좁혀서 덮는 쪽이 맞습니다.
매니페스트에 박힌 해시가 계속 엉뚱하면, 그 값이 어느 레포의 HEAD 와 일치하는지 빌드 두세 개만
비교해 봐도 어느 쪽이 주입되고 있는지 바로 나옵니다.
댓글 0