我正在尝试编写一个SVN post-commit脚本,目的是要意识到,只要其中一个开发人员提交到SVN存储库,它就会触发Jenkins构建并自动部署项目。
我按照 Subversion Plugin 中的说明操作,我的提交后就像:
#!/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错误" ,我检查了Jenkins中的 Global Security 配置:
我根本不知道为什么会发生错误。
对于" 403 Forbidden错误" ,参考上一个屏幕截图,我提供了一个用户/密码,JENKINS_USER / JENKINS_PW(即使他们说我会使用API令牌而不是密码的纯文本),为什么禁止它?
答案 0 :(得分:0)
请尝试使用以下方法:
您只需要一个插件即Subversion插件。然后,进入Jenkins→job_name→构建触发器部分→(i)远程触发构建(即从脚本)验证令牌:Token_name
转到SVN服务器的hooks目录,然后触发以下命令:
cp post-commit.tmpl post-commit
chmod 777 post-commit
chown -R www-data:www-data post-commit
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
答案 1 :(得分:0)
我通过修改https://plugins.jenkins.io/subversion/
中的示例脚本解决了该问题。1)创建一个Jenkins用户(您要执行提交后命令的用户) 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