쉘 실행에 실패하면 jenkins 빌드에 실패하지 마십시오.


132

내 빌드 프로세스의 일부로 git commit을 실행 쉘 단계로 실행 중입니다. 그러나 작업 공간에 변경 사항이 없으면 Jenkins가 빌드에 실패합니다. 커밋 할 변경 사항이 없으면 git이 오류 코드를 반환하기 때문입니다. 빌드를 중단 하거나이 경우 불안정한 것으로 표시하고 싶습니다. 어떤 아이디어?


커밋 할 것이 있는지 확인하고 그러한 경우에만 커밋 하시겠습니까? stackoverflow.com/questions/5139290/…
Anders Lindahl

답변:


210

명령 이 실패 할 때 추가 실행을 중지하려면

command || exit 0

명령 이 실패 할 때 실행을 계속하려면

command || true


12
|| exit 0첫 번째 경우에는 필요하지 않습니다 command. false를 반환하면 실행이 중지됩니다. 즉, 두 번째 옵션은 매우 유용합니다!
Nir Alfasi

20
@alfasin 당신은 문제를 이해하지 못합니다. OP는 Jenkins 빌드가 실패하는 것을 원하지 않습니다. exit 00이 아닌 종료 코드가 빌드에 실패하기 때문에 우리는 반드시해야합니다 .
Quolonel Questions

1
이 경우 "명령이 실패 할 때 추가 실행을 중지하려면 :"에서 "명령이 실패 할 때 추가 실행을 중지하고 Jenkins 작업을 성공한 것으로 표시 :"에서 문구를 변경합니다.
Nir Alfasi

1
@alfasin 나는 Quolonel Questions의 불쾌한 말이 전문가가 아니라는 것에 동의하지만, 그가 말한 바에 맞았습니다. "exit 0"은 작업을 성공으로 표시하지 않습니다. 현재 빌드 단계가 성공한 것으로 표시됩니다. 다음 빌드 단계 중 하나에서 작업이 계속 실패 할 수 있습니다.
noamik

1
고마워요! / bin / bash + e를 사용하여 오류가 발생하지 않도록하기 때문에 "ssh를 사용하여 원격 호스트에서 쉘 실행"플러그인 기능에 특히 유용합니다. 또한 빌드에 실패하지 않는 명령을 선택한다는 아이디어가 마음에 듭니다.
leeman24

80

Jenkins는 다음을 사용하여 쉘 빌드 단계를 실행합니다. /bin/sh -xe 기본적으로 합니다. -x실행 된 모든 명령을 인쇄하는 것을 의미합니다. -e스크립트의 명령 중 하나라도 실패하면 실패로 종료하는 것을 의미합니다.

그래서 귀하의 경우에 일어난 일은 git command exit with 1, 그리고 기본값으로 인해 -e 매개 변수 쉘은 0이 아닌 종료 코드를 선택하고 나머지 스크립트를 무시하고 단계를 실패로 표시합니다. 빌드 단계 스크립트를 여기에 게시 할 수 있으면이를 확인할 수 있습니다.

이 경우 넣어보십시오 #!/bin/sh 옵션없이 스크립트가 실행되도록 . 또는 set +e빌드 단계에서이 동작을 무시하기 위해 또는 비슷한 작업을 수행하십시오 .


편집 : 주목해야 할 또 다른 사항은 쉘 스크립트 의 마지막 명령 이 0이 아닌 코드를 반환 하면이 설정을 사용하더라도 전체 빌드 단계가 여전히 실패로 표시됩니다. 이 경우 간단하게echo 명령을 피하기 위해 명령을 끝에 .

다른 관련 질문


41

git을 푸시 할 것이 없으면 종료 상태 1을 리턴합니다. 쉘 빌드 단계 실행이 각각 실패로 표시됩니다. OR 문을 사용할 수 있습니다 || (더블 파이프).

git commit -m 'some messasge' || echo 'Commit failed. There is probably nothing to commit.'

즉, 첫 번째 실패 (반환 종료 상태> 0) 인 경우 두 번째 인수를 실행하십시오. 두 번째 명령은 항상 0을 반환합니다. 푸시 할 항목이 없으면 (종료 상태 1-> 두 번째 명령 실행) echo는 0을 반환하고 빌드 단계를 계속합니다.

빌드를 불안정한 것으로 표시하려면 빌드 후 단계 Jenkins Text Finder를 사용할 수 있습니다. 콘솔 출력, 패턴 일치 (에코) 및 빌드를 불안정한 것으로 표시 할 수 있습니다.


27

Jenkins에게 실패하지 않도록 말하는 또 다른 부드러운 방법이 있습니다. 빌드 단계에서 커밋을 격리하고 셸이 실패하지 않도록 설정할 수 있습니다.

set +e
git commit -m "Bla."
set -e

2
set -e종료 코드에 관계없이 실행할 명령 뒤에 추가하십시오 . 그렇지 않으면 의도하지 않은 명령이 실행될 수 있습니다. 나는 같은 것을했다, 그래서 자신을 오류를 처리하고 싶었 : = "{?} $"세트 -e # 핸들 종료 코드 로직``세트 + 전자는 -m 커밋 "즐"EXIT_CODE을
jcasner

8

Jenkins는 단계의 리턴 값으로 단계의 성공 / 실패를 판별합니다. 쉘의 경우 마지막 값의 리턴이어야합니다. Windows CMD 및 (POSIX) Bash 셸 모두 exit 0마지막 명령 으로 사용하여 반환 값을 수동으로 설정할 수 있어야합니다 .


git commit -m "message"exit 0
Ben

@Ben exit 0Jenkins 설치에서 여러 빌드에서 "execute windows batch command"와 함께 사용 하면 예상대로 작동합니다. 다른 일이 일어나고 있어야합니다. 콘솔 로그의 관련 부분을 게시 할 수 있습니까?
jwernerny

첫 번째 단계에서 git commit -m "blah"와 함께 사용하고 있습니까? 기계에서 수동으로 bat 스크립트를 작성하려고 시도하고 git 명령 뒤에 echo와 exit 0을 넣습니다. 커밋 할 것이 없을 때 다른 명령은 실행되지 않습니다.
Ben

@xiawei의 답변을 참조하십시오. Jenkins의 기본 동작은 #!/bin/sh -xv오류가 발생하면 스크립트를 중지시키는 쉘을 실행하는 것 입니다.
스티븐은 쉽게 즐겁게

8

여기에있는 답변을 사용 하여이 작업을 수행 할 수있었습니다.

오류없이 아무것도 커밋하는 방법은 무엇입니까?

git diff --quiet --exit-code --cached || git commit -m 'bla'

1
위의 내용은 " git diff명령을 실행하고 실패하면 git commit명령을 수행하십시오. 기본적으로, 커밋 할 것을 git diff찾은 경우에만 커밋을 수행합니다. 그러나 @jwernerny 답변은 exit 0마지막 문장 으로 추가 할 수 있어야합니다 . 젠킨스가 성공한 것으로 간주하도록하는 스크립트라면 리눅스 쉘 단계를한다면 실패 할 수있는 시나리오를 생각해 볼 수있다. 그러나 배치에서는 항상 작동해야한다.
Slav

@Ben Jenkins는 여기 (중간)에 /bin/sh -xe언급 된 것처럼 기본적으로 쉘 빌드 단계를 실행 합니다. 당신은 넣어 시도 할 수 있도록 하거나 할 단계 0이 아닌 코드도 하나의 명령 안에 출구의 나머지 계속하는이 동작을 재정의하는 빌드 단계의 상단에#!/bin/bashset +e
Xiawei 장

8

Jenkins가 실패하는 것을 방지하기 위해 제목에있는 (일반적인) 질문에 종료 코드 1이 표시되지 않도록 할 수 있습니다. ping의 예 :

bash -c "ping 1.2.3.9999 -c 1; exit 0"

이제 예를 들어 ping 출력을 얻을 수 있습니다.

output=`bash -c "ping 1.2.3.9999 -c 1; exit 0"`

물론을 ping ...포함하여 모든 명령을 사용할 수 있습니다 git commit.



6

텍스트 파인더 플러그인을 사용할 수 있습니다 . 출력 콘솔에서 원하는 표현을 확인한 다음 빌드를로 표시 할 수 있습니다 Unstable.


이것은 유망한 것처럼 보였지만 어떤 이유로 든 빌드에 실패했습니다.

4

여러 셸 명령의 경우 다음을 추가하여 실패를 무시합니다.

set +e commands true

여기에 이미지 설명을 입력하십시오


나는 일반적으로 설정 해제를 권장하지 않습니다. 특정 명령의 반환 값을 무시하려면 "|| true"또는보다 의미있는 true를 반환하는 것을 추가 할 수 있습니다. stop-service.sh || 에코 서비스는 아래 이미
라울 살리나스 - Monteagudo

3

이 명령을 쉘 블록에 넣으면 :

false
true

빌드는 실패 (최소한 0이 아닌 종료 코드 1)로 표시되므로 무시하도록 +를 추가 (set + e) ​​할 수 있습니다.

set +e
false
true

실패하지 않습니다. 그러나 (set + e)를 배치해도 실패합니다.

set +e
false

마지막 쉘 명령은 0으로 종료해야하기 때문입니다.


2

다음 은 변경 사항이있는 경우에만 커밋 하여 수은 에 적용됩니다. 따라서 커밋이 실패하는 경우에만 빌드가 실패합니다.

hg id | grep "+" || exit 0
hg commit -m "scheduled commit"

0

몇 가지 팁이있는 또 다른 대답은 누군가에게 도움이 될 수 있습니다.

다음 규칙으로 명령을 분리해야합니다. .

command1 && command2-command1이 성공한 경우에만 command2가 실행됨을 의미합니다.

command1 ;command2-명령 1의 결과에도 불구하고 명령 2가 실행됨을 의미합니다.

예를 들면 다음과 같습니다.

String run_tests = sh(script: "set +e && cd ~/development/tests/ && gmake test ;set -e;echo 0 ", returnStdout: true).trim()
println run_tests 

다음 코드가 차단되는 동안 (테스트가 실패한 경우) set -eecho 0명령 으로 성공적으로 실행됩니다 gmake test.

String run_tests = sh(script: "set +e && cd ~/development/tests/ && gmake test && set -e && echo 0 ", returnStdout: true).trim()
println run_tests 

약간의 잘못 및 명령 set -eecho 0에서가 && gmake test && set -e && echo 0으로 건너 뜁니다 println run_tests실패했기 때문에, 문 gmake test젠킨스 빌드를 중단됩니다. 해결 방법으로로 전환 할 수 returnStatus:true있지만 명령의 출력이 누락됩니다.


0

이 답변은 정확하지만를 지정하지 않는 || exit 0또는 || true이동 쉘 명령의 내부 . 보다 완벽한 예는 다음과 같습니다.

sh "adb uninstall com.example.app || true"

위는 작동하지만 다음은 실패합니다.

sh "adb uninstall com.example.app" || true

아마도 다른 사람들에게는 분명하지만, 이것을 깨닫기 전에 많은 시간을 낭비했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.