Jenkins GIT_COMMIT — Git 플러그인의 덮어쓰기

CI·CD2분조회

파이프라인의 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 스코프

env.X = ... 대입이 안 먹히면, 그 변수를 플러그인이 관리하는지 의심합니다. Git 플러그인의 GIT_COMMIT 처럼 EnvironmentContributor 로 주입되는 값은 읽을 때마다 재계산돼서, 스크립트 대입을 무시합니다. Job SCM 과 빌드 대상이 다른 파이프라인에서 특히 헷갈립니다 — 플러그인이 늘 Job SCM 을 가리키기 때문입니다. 그런 값은 전역에 대입하려 하지 말고 withEnv 로 스코프를 좁혀 덮어씁니다.

  1. 불러오는 중