【问题标题】:How do I trigger Jenkins build with SVN post-commit?如何使用 SVN 提交后触发 Jenkins 构建?
【发布时间】:2015-04-03 12:18:28
【问题描述】:

我正在尝试编写一个 SVN 提交后脚本,目的是意识到,每当开发人员提交到 SVN 存储库时,它都会触发 Jenkins 构建并自动部署项目。

我按照 Subversion Plugin 中的说明进行操作,我的 post-commit 是这样的:

#!/bin/sh
#
# Jenkins SVN Build trigger script by Wessel de Roode Aug' 2011
#

# Please adjust
SERVER=localhost                                                
PORT=8080        
WGET=/usr/bin/wget
SVNLOOK=/usr/bin/svnlook

# Don't change below this point
###############################

REPOS="$1"
REV="$2"
UUID=`$SVNLOOK uuid $REPOS`

echo "--------------------------------">>${REPOS}/post-commit.log
#
# Check if "[X] Prevent Cross Site Request Forgery exploits" is activated
# so we can present a valid crum or a proper header
BREAD_URL='http://'${SERVER}:${PORT}'/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'

CRUMP=`$WGET --append-output=${REPOS}/post-commit.log --output-document -${BREAD_URL}`
if [ "$CRUMP" == "" ]
then
    HEADER="Content-Type:text/plain;charset=UTF-8"
else
    HEADER=$CRUMP
fi

$WGET \
    --http-user=JENKINS_USER --http-password=JENKINS_PW \
    --header ${HEADER} \
    --post-data "`$SVNLOOK changed --revision $REV $REPOS`" \
    --append-output=${REPOS}/post-commit.log  \
    --output-document "-"\
    --timeout=2 \
    http://${SERVER}:${PORT}/jenkins/subversion/${UUID}/notifyCommit?rev=$REV\

# Uncomment line below for debug
echo $(date) HEADER=${HEADER} REPOS=$REPOS REV=$REV UUID=${UUID} http://${SERVER}:${PORT}/subversion/${UUID}/notifyCommit?rev=$REV >>${REPOS}/post-commit.log

当我从 SVN 客户端提交某些内容时,日志如下:

--2015-04-03 21:01:20--  http://localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,%22:%22,//crumb)
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8080... connected.
HTTP request sent, awaiting response... 404 Not Found
2015-04-03 21:01:20 ERROR 404: Not Found.

Fri Apr 3 21:01:20 KST 2015 HEADER=Content-Type:text/plain;charset=UTF-8 REPOS=/home/share/svn/myblog REV=30 UUID=d6922f4b-358e-4015-8fd3-a25217326040 http://localhost:8080/subversion/d6922f4b-358e-4015-8fd3-a25217326040/notifyCommit?rev=30
--2015-04-03 21:01:20--  http://localhost:8080/jenkins/subversion/d6922f4b-358e-4015-8fd3-a25217326040/notifyCommit?rev=30
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8080... connected.
HTTP request sent, awaiting response... 403 Forbidden
2015-04-03 21:01:20 ERROR 403: Forbidden.

对于“404 Not Found error”,我检查了Jenkins中的全局安全配置:

我完全不知道为什么会发生错误。

对于“403 Forbidden error”,参考之前的屏幕截图,我提供了一个用户/密码,JENKINS_USER/JENKINS_PW(尽管他们说我将使用 API 令牌而不是明文密码),为什么会被禁止?

【问题讨论】:

  • localhost 正确吗?即,您的 SVN 服务器和 Jenkins 服务器是同一台机器吗?
  • @PatrickQuirk 感谢您的关注。是的,它们在同一台机器上运行,我这样做是为了学习。

标签: svn jenkins post-commit


【解决方案1】:

请尝试以下方法:

您只需要一个插件,即 Subversion 插件。然后简单地进入 Jenkins → job_name → Build Trigger 部分 → (i) Trigger build remote (i.e from scripts) Authentication token: Token_name

转到 SVN 服务器的 hooks 目录并在触发以下命令后:

  1. cp post-commit.tmpl post-commit
  2. chmod 777 post-commit
  3. chown -R www-data:www-data post-commit
  4. vi post-commit 注意:所有行都应该被注释掉。最后添加以下行。

语法(适用于 Linux 用户):

/usr/bin/curl http://username:API_token@localhost:8081/job/job_name/build?token=Token_name

语法(适用于 Windows 用户):

C:/curl_for_win/curl http://username:API_token@localhost:8081/job/job_name/build?token=Token_name

【讨论】:

  • 它真的应该是 Windows 的正斜杠吗(第一部分,C:/curl_for_win/curl)?
  • 你甚至不需要 curl,另一种方法是使用 wget。
【解决方案2】:

我通过修改里面的示例脚本解决了这个问题:https://plugins.jenkins.io/subversion/

1) 创建一个 Jenkins 用户(您希望执行 post-commit 命令的用户) 2) 为该用户创建 API 令牌。 3) 使用用户名和令牌更改附加的脚本:

    #!/bin/bash
REPOS="$1"
REV="$2"

# No environment is passed to svn hook scripts; set paths to external tools explicitly:
WGET=/usr/bin/wget
SVNLOOK=/usr/bin/svnlook

# If your server requires authentication, it is recommended that you set up a .netrc file to store your username and password
# Better yet, since Jenkins v. 1.426, use the generated API Token in place of the password
# See https://wiki.jenkins-ci.org/display/JENKINS/Authenticating+scripted+clients
# Since no environment is passed to hook scripts, you need to set $HOME (where your .netrc lives)
# By convention, this should be the home dir of whichever user is running the svn process (i.e. apache)
HOME=/var/www/

UUID=`$SVNLOOK uuid $REPOS`

# Password correcponds to the API token.
JENKINS_USER="user"
JENKINS_PASSWORD="1166085xxxxxxxxe50067fb91866"

NOTIFY_URL="subversion/${UUID}/notifyCommit?token=${JENKINS_PASSWORD}?rev=${REV}"
CRUMB_ISSUER_URL='crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'

function notifyCI {
    # URL to Jenkins server application (with protocol, hostname, port and deployment descriptor if needed)
    CISERVER=$1

    # Check if "[X] Prevent Cross Site Request Forgery exploits" is activated
    # so we can present a valid crumb or a proper header

    HEADER="Content-Type:text/plain;charset=UTF-8"
    CRUMB=`$WGET --auth-no-challenge --output-document - ${CISERVER}/${CRUMB_ISSUER_URL}`
    if [ "$CRUMB" != "" ]; then HEADER=$CRUMB; fi

      echo "$WGET --auth-no-challenge  --http-user=${JENKINS_USER}  --http-password=${JENKINS_PASSWORD} --header $HEADER --post-data \"`$SVNLOOK changed --revision $REV $REPOS`\" --output-document \"-\" --timeout=2 ${CISERVER}/${NOTIFY_URL}"
      $WGET --auth-no-challenge  --http-user=${JENKINS_USER}  --http-password=${JENKINS_PASSWORD} --header $HEADER --post-data "`$SVNLOOK changed --revision $REV $REPOS`" --output-document "-" --timeout=2 ${CISERVER}/${NOTIFY_URL}

}
# The code above was placed in a function so you can easily notify multiple Jenkins servers:
notifyCI "<base-url>" 1>&2 >> /opt/svn/repo/rds/hooks/post-commit.log

【讨论】:

    猜你喜欢
    • 2012-04-18
    • 1970-01-01
    • 2015-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多