使用 POST COMMIT 挂钩在 SVN 存储库上提交代码时自动触发 Jenkins 作业

Jenkins job auto-triggering when code commit on SVN repo using POST COMMIT hook

我正在尝试使用 Jenkins、docker 和 Ansible 实施 CI/CD 管道。我正在为我的版本控制系统使用 SVN 代码存储库。对于部署和 SVN 代码回购,我使用的是 AWS EC2。部署和代码存储库在单独的 VM 中。

我的要求

当我将代码提交到 SVN 存储库时,我需要触发一个 Jenkins 作业。该作业将调用一个 ansible playbook.Later 它将构建项目、构建 Docker 图像并部署到 EC2 中。因此,对于我的 SVN 代码存储库的任何更改,我需要构建 Jenkins 作业。

我目前的尝试

我在 $repo/hooks 文件夹下的 post-commit.tmpl 文件中添加了以下脚本。

REPOS=""
REV=""
UUID=`svnlook uuid $REPOS`
/usr/bin/wget \
  --header "Content-Type:text/plain;charset=UTF-8" \
  --post-data "`svnlook changed --revision $REV $REPOS`" \
  --output-document "-" \
  --timeout=2 \
  http://server/subversion/${UUID}/notifyCommit?rev=$REV

以下为截图

并检查了 "Poll SCM option in Jenkins Job":

注意: 我没有在看 minute/hours/week 从回购中提取的时间表。取而代之的是,我正在查看何时有代码更改,然后我需要构建 Jenkins 项目。所以我没有添加任何时间表。

但我仍然没有获得 Jenkins 中的最新代码。如何找出与我的配置相关的问题?

已更新 post-commit.tmpl 文件

如果不查看实际错误和日志,很难解决此问题。但是,可能的原因之一是您的 SVN 服务器需要身份验证。您应该指定正确的用户名和密码,并确保该用户帐户对 SVN 存储库具有读取权限。

就像@bahrep 所说的那样,很难解决这样的问题,但我的猜测是你的 post-commit 钩子不起作用,因为 "Prevent Cross Site Request Forgery exploits" Jenkins 安全选项(你已经确认它已启用)。

From Jenkins Wiki:

If your Jenkins uses the "Prevent Cross Site Request Forgery exploits" security option, the above request will be rejected with 403 errors ("No valid crumb was included"). The crumb needed in this request can be obtained from the URL http://server/crumbIssuer/api/xml (or /api/json). This can be included in the wget call above with something like this:

--header `wget -q --output-document - \
  'http://server/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'`

确认此安全选项是否导致问题的最简单方法是禁用它并尝试 post-commit 挂钩是否有效。如果是,再次启用并尝试使用碎屑配置钩子。 (最后,你想让事情变得安全:))

还要确保 Jenkins 已启用匿名读取访问权限:

For this to work, your Jenkins has to allow anonymous read access (specifically, "Job > Read" access) to the system. If access control to your Jenkins is more restrictive, you may need to specify the username and password, depending on how your authentication is configured.

编辑

我认为问题的发生是因为您没有提供 Jenkins 实例地址。在您的 webhook 示例中,您有:

http://server/subversion/${UUID}/notifyCommit?rev=$REV

您应该将 server 更改为您的 Jenkins 实例地址(IP、域或 ip 和端口。这取决于您的配置。)。

http://yourjenkins.com/subversion/${UUID}/notifyCommit?rev=$REV

http://<IP>:<Port>/subversion/${UUID}/notifyCommit?rev=$REV

http://<IP>/subversion/${UUID}/notifyCommit?rev=$REV

或者如果你 运行 一切都在本地(包括 svn repo):

http://localhost:8080/subversion/${UUID}/notifyCommit?rev=$REV

但记得有:

  • "Prevent Cross Site Request Forgery exploits" 安全选项已禁用(稍后您将创建 webhook 以使用此选项,现在我们要找到根本原因)
  • "allow anonymous read access" 启用安全选项

我认为钩子脚本工作得很好,但它被发送到任何地方。这可以通过记录您的挂钩脚本轻松检查。只需在钩子末尾添加:

echo "`$REPOS` change to revision `$REV` triggered @ `date`" >> ${REPOS}/post-commit-hook.log

并查看是否在创建提交日志文件之后。如果是,则表示 wget 请求发送错误。

有一种更简单的方法...通过简单地定义触发器的时间表:

或使用 trigger builds remotely,如果想要推送而不是拉取解决方案,这需要使用预定义的 API 标记发布到 https://username:api-token@JENKINS_URL/job/Example/buildauthenticating scripted clients 解释一下。仅根据建议的更改进行构建,因为其他一切都会不必要地消耗处理能力(等同于金钱)。

我做了很多尝试,通过使用答案中的指导来解决这个问题。最后我得到了我面临的实际问题。我在文件 "post-commit.tmpl" 中添加了 post-commit 脚本。这个文件默认是我在创建 SVN 存储库时得到的。而不是添加 "post-commit.tmpl" 只需要创建文件 "post-commit"。它解决了我的问题。