用于在github版本上发布travis ci构建工件的脚本

ci-release-publisher的Python项目详细描述


CI发行商

用于在GitHub版本上发布Travis CI构建工件的脚本。

主要面向发布夜间/连续的版本,travis ci不支持这些版本,但也可以用于发布发布版本。

目录

功能

  • 每晚/连续发布的两种口味:
    • 最新版本:aci-<;branch>;-最新的标记版本,将保持更新,以包含分支的最新travis ci生成的生成工件
    • 带编号的发行版:aci-<;branch>;-<;build number>;带标记的发行版,将包含分支的travis ci build的生成工件
      • 编号版本的保留策略:
        • 只保留分支的最后N个编号的版本,额外编号的版本将从最低版本开始删除(即最旧版本优先)
        • 只保留在过去n秒内发布的编号版本(即删除所有早于n秒的编号版本)
  • 标签释放:仅在标签按下时进行的常规释放
  • 分别自定义三种发布类型的发布信息:
    • 发行名称
    • 发布体(例如,将其设置为所有生成工件的散列列表)
    • 草稿标记(例如,如果您希望发行版是私有的)
    • 预发布标志(例如,当每晚都是产品发布时!)
    • 目标提交
  • 竞争条件证明-无论并行运行的每个生成有多少个生成或作业,任何版本都不会因竞争条件而损坏
  • 允许发布到不同GitHub存储库的发布页面
  • 支持公共github repo(已测试),但也应与私有github repo和自托管github实例(均未测试)一起使用。

术语

让我们定义一些我们将在整个文件中使用的术语,如果您不了解它们,可能会让您感到困惑。

CI发行发行商条款

请参见功能中的最新版本编号版本标记版本

特拉维斯CI术语

作业-一个单独的过程,包括git克隆存储库,然后在计算机上运行任意命令,通常用于构建和/或测试在存储库中。

阶段-一组作业。阶段允许强制执行作业执行顺序。一个阶段中的所有作业并行运行,但是每个阶段都按顺序运行,例如,在阶段1中的所有作业完成之前,阶段2中的作业不会开始运行。此功能有时也称为管道,例如在Gitlab CI中。

构建-一组阶段。如果生成中至少有一个作业失败,则生成将标记为失败。每次推送到配置了travis ci的github存储库时,都会创建构建。在非常小的情况下,一个构建只有一个阶段,其中包含一个作业。

下面是一个包含5个阶段和15个作业的构建示例:url屏幕快照

GitHub术语

release-允许将可下载文件与现有git标记关联的功能。主要用于软件及软件相关文件的分发。所有版本都可以在github存储库的专用版本页上查看,其中的版本按创建时间排序。

草稿发布-一个"私有"的发布,即仅对具有对存储库的私有访问权限(写入或管理存储库权限)的人可见。草稿发行版可以更改为非草稿发行版,将其公开,如果以前不存在,则为其创建git标记。

预发布版本—明显标记为未准备生产的版本。适合夜间/连续发布。

ci发行商与travis ci的github发行部署之比较

travis ci提供了许多人都熟悉的github release s部署选项,让我们快速比较一下ci release publisher与travis ci部署选项的区别。

简短比较

如果您不想通读,这里有一张表格总结比较结果。

<表><广告>功能 CI发行商 特拉维斯指数 < /广告><正文>标签发布 >是 >是最新版本 >是 NO*编号版本 >是>可定制的发布信息 >是是**竞争条件证明 >是>适当的草稿发布 >是

*--可以使用一些额外的bash命令来完成,但它不是travis ci的github发布部署功能集的一部分,也不会是竞争条件证明。

**--travis ci的发行体不能包含新行,因此不能在其中包含多行变更日志,这意味着您将无法列出项目的哈希值,例如。

详细比较

travis ci的github releases部署选项非常适合非草稿标记发布。事实上,如果这是您所需要的,那么您应该强烈考虑在ci release publisher上使用travis ci的github release s部署选项,因为travis ci提供的发布自定义量与ci release publisher差不多(无需在发布体中支持新行)。

然而,在这一点上,travis ci的github releases部署的有用性结束了。如果要设置包含新行的发布体、创建竞赛条件验证标记发布、创建任何类型的草稿发布、创建最新发布或创建编号的发布,travis ci将失败。

释放车身中的新管路

travis ci在指定r时不支持新行由于Travis CI的组件处理部署遇到新行问题,Elease的正文。CI发行商没有此限制。

标签释放

travis ci的标签发布不能证明竞争条件。您可以将标记推送到github,github将创建一个travis ci构建,然后删除标记并再次推送到github,这一次应该指向一些新的修复提交,这将创建另一个travis ci构建。现在,您将有两个travis ci构建并行运行,并将工件上载到同一个标记版本,这是一个竞争条件。您可能最终会发布一个版本,其中一些工件来自第一个版本,而另一些工件来自第二个版本,其中包含您所推送的修复程序。ci release publisher不存在此问题,它确保标记发布仅包含该标记的最新版本的工件。

草稿发布

travis ci的草稿版本的问题是,对于非草稿版本,travis ci只为包含所有作业工件的整个构建创建一个单独的版本,这正是您想要的,而对于草稿版本,travis ci创建了许多草稿版本,一对一的工作,在建设,这不是你想要的。例如,如果您有10个作业,那么您将得到10个草稿版本,每个版本只包含一个特定作业的工件,而实际上您只希望得到一个草稿版本,其中包含所有10个作业的工件。在travis ci中,只要将draft:false更改为draft:true就会极大地改变行为。ci release publisher没有这个问题,它只创建一个包含所有作业工件的最终版本,无论是在创建草稿版本还是非草稿版本时。

最新版本

就最新版本的问题而言,travis ci的github版本部署根本不支持创建这样的版本。别无选择。但是,有一个解决方法可以在travis ci上创建最新版本,但它需要运行一些额外的bash/git命令,并且有可能导致一个版本被破坏,即它允许多个版本同时编辑同一版本。ci release publisher支持创建最新版本,并且不带竞赛条件。

编号发布

travis ci也不支持创建带编号的版本。尽管可以使用创建最新版本时所用的解决方法创建它们,但如果不使用github api,则无法轻松删除以前编号的版本。如果您认为可以通过扩展工作区来使用git命令行程序来删除git标记以删除版本来避免使用github api,那么这是行不通的,如果github版本的git标记被删除,则版本不会被删除,它仍然存在,但会更改为草稿。以这种方式删除以前编号的版本也会有竞争条件,因为在删除之前编号的版本时,它们可能仍在由其他版本创建的过程中,这可能会导致这些版本创建不完整的版本。要做到这一点,您需要重新设计ci发布服务器。

处理赛道条件

特别注意确保ci release publisher避免了竞争条件,特别是那些可能破坏发布的竞争条件--导致发布不包含所有工件,或者某个发布中某些工件来自同一个构建,从而导致一次提交,但另一个来自另一个。本节将讨论ci release publisher功能,如果天真地实现,它们将如何具有竞争条件,以及ci release publisher如何避免这些竞争条件。这不是竞争条件的完整列表,ci发行商必须处理wi但是它提供了一个关于ci发行商如何工作的好主意。

竞态条件可能发生在两个主要点:作业并行运行时和生成并行运行时。我们认为,只有在同一个分支/标记中的生成与在ci release publisher中来自不同分支/标记的生成不会相互影响。

并行运行的作业

ci release publisher的目标是创建一个包含生成生成作业的所有工件的工件的发布。一个简单的方法是让jobs创建一个github版本,让他们将工件上传到其中,就这样,完成了——我们将拥有一个包含所有jobs工件的单一版本。

虽然如果作业按顺序执行,这种简单的实现会起作用,但当两个或多个作业并行运行并试图创建github版本时,它会有一个竞争条件。作业会检查github api,看看这个构建中的其他作业是否已经创建了一个版本,应该使用这个版本而不是创建一个新版本,但是因为它们可以同时检查所有的版本,多个作业最终可能会发现还没有其他作业创建发布,并决定创建一个发布,这将导致为此生成创建多个发布,生成工件在其中进行划分。为一个构建创建多个版本肯定不是我们想要的,而且也没有简单的方法来阻止它。Github API很高兴地创建尽可能多的相同草稿版本实例,而不会引发任何错误,因此我们不能将Github API用作一个竞赛关卡,它只会通过第一个试图创建版本的作业,而拒绝所有其他作业。

ci release publisher通过序列化生成的发布的创建来解决此问题,它使得只有一个作业负责创建发布,但这样做的代价是在生成中有一个单独的阶段。ci release publisher使每个生成工件的作业创建一个唯一的临时存储发布,其中包含该作业的生成工件,然后在下一阶段,它从临时存储发布中收集所有这些工件,删除这些发布,并创建包含所有这些工件的适当版本。这样,只有一个作业可以创建(最终)版本,因此不会出现比赛条件,因为它不会与任何人比赛。

虽然这成功地解决了种族问题,但它有一个小缺点。如果生成在到达发布阶段之前失败,则不会删除所有这些临时存储版本,并且会在发布页面上乱扔东西,尽管只有repo管理员可以看到其中列出的草稿版本。这主要是通过在发布阶段检查构建是否失败并删除这些发布之前进行作业来解决的,这样我们就不必只依赖发布阶段来删除它们。

并行运行的生成

并行运行生成的主要问题是,多个生成可以同时修改同一版本。

最新版本

最新版本是包含分支最新生成的工件的版本。最新版本始终具有相同的ci-<;branch>;-latest标记名,因此您可以在自述文件或网站中轻松链接到它,因为url不会更改。每个分支始终不超过一个最新版本。最新版本功能的一个简单实现是让每个版本删除现有的最新版本(如果有的话),并用当前版本的工件创建一个新版本。

如果生成是按顺序执行的,那么这种简单的实现就可以工作,但是当两个或多个生成并行运行并试图删除和创建最新版本时,它就有了竞争条件。有几件事可能会出错。首先,我们可以让一个构建删除另一个构建可能正在上载工件的版本,这将使上载的构建抛出异常失败——这是理所当然的,因为我们认为一个版本的工件丢失了一个失败。其次,我们可能会遇到这样的情况:由于代码更改或删除某些生成步骤,较新的生成比较旧的生成提前完成,这将导致较旧的生成是最后一个要删除的生成,然后重新创建最新版本,这意味着最新版本将包含工件旧版本而不是新版本的。

只有当当前版本是分支的最新版本时,ci release publisher才通过更新(删除然后重新创建)最新版本来解决此问题。它检查travis ci api以获取分支的最新版本的内部版本号,如果它不是当前版本的内部版本号,则跳过更新最新版本,将其保留为较新版本。这样,只有一个构建修改了最新版本——修改被序列化。这解决了上述问题中的第一个和第二个问题。它还可以保护最新版本,防止在重新启动旧的travis ci版本时降级以包含旧版本的工件。

矛盾的是,这种解决方案的缺点是,只有最新的版本才能更新最新的版本。如果您有多个生成并行运行,并且除了最新版本之外,所有成功的生成都将传递更新最新版本,而将其保留为最新版本,但因为该生成已失败,它不会到达发布阶段,也不会更新任何版本,因此您最终会发现最新版本根本没有更新。这没有解决方法,所以请确保您的生成不会失败,并用一个固定的生成跟踪失败的生成。

顺便说一句,您可能会注意到这个解决方案仍然忽略了竞争条件,特别是在旧版本检查travis ci api以确保它是分支的最新版本之后创建新版本的情况--这可能会导致两个版本都更新最新版本两个版本都会认为它们是最新的版本。但是,这样的竞争条件被排除在外,因为在使用travis ci api进行检查之后,旧版本只需要几次github api调用(实际上不到一秒钟)就可以更新最新版本。它所要做的就是1)调用github api来删除以前的最新版本,2)再次调用github api来更改已经创建的版本的标记名,其中所有工件都已上载到正确的最新版本标记名。新创建的构建可能还没有开始,更重要的是到了发布阶段,到了更新最新版本的程度,在这么短的时间内。所以这两个版本不应该同时更新发行版。

标签释放

Tag Release的实现方式与最新版本非常相似,它不处理任何新的比赛条件问题,因此没有什么真正要说的。

编号发布

编号版本是包含特定构建的工件的版本。有编号的版本使用ci-<;branch>;-<;build number>;标记名,因此与最新版本不同,版本url总是不同的。带编号的版本有一个保留策略选项,用于指示何时应删除现有带编号的版本。编号版本功能的一个简单实现是,使每个版本都为此版本创建一个新的编号版本,并删除要由保留策略删除的现有编号版本。

如果按顺序执行生成,这种简单的实现将起作用,但当两个或多个生成并行运行时,它有一个竞争条件,因为当新生成删除该版本时,旧生成可能仍在将工件上载到其编号的版本的过程中,由于无法将其余构件上载到不再存在的版本,导致旧版本出错这将导致旧版本失败。

ci release publisher通过仅对已完成的版本执行保留策略来解决此问题。它可以这样做,因为它可以区分正在进行的版本和已完成的版本。当一个发行版刚刚创建时,它有一个特殊的标记名,表示它正在进行中,一旦所有的工作都完成了,它就会被重命名为一个合适的标记名。ci release publisher忽略所有正在进行的版本,因为如果不失败,则仍在处理这些版本的生成,只考虑已完成的版本。这不仅仅是一个有编号的版本,ci release publisher为所有的版本类型都这样做,但在有编号的版本情况下,这一点尤为重要。它还允许存储库所有者查看哪些自动发布已完成,哪些仍在进行中或失败而从未完成。

这个解决方案有几个缺点。首先,如果发布作业在运行过程中失败或被取消,它可能会留下一个正在进行的草稿发布,并将发布页面乱七八糟。根据travis ci api,这个问题可以通过添加额外的清理代码来解决,如果相应的版本不再运行,这些代码将删除现有的正在进行的版本。其次,由于保留策略只考虑已完成的版本,因此正在进行的版本将滑过保留策略。例如,如果有n个版本并行运行,且所有版本都有进行中的版本,并且保留策略设置为最多保留m个最新编号的版本,则那些n个进行中的版本将滑过保留策略,从而保留n+m个编号的版本。这个问题没有解决办法。实际上,这并不是什么大问题,因为实际中的n往往很小,甚至为零,下一个版本将执行保留策略并删除任何额外编号的版本,只保留m。

安装

确保使用Python3.5或更高版本。

来源:

python setup.py install

来自PYPI:

pip install ci_release_publisher

签名

PYPI包是用以下主键的子键进行PGP签名的:

Key fingerprint = 1D4E 9375 AD9B D50F 80FF  55AC 6F55 0977 4B1E F0C2

签名被上传到pypi。注意pip不验证签名,必须手动验证。此外,PYPI网站故意从下载列表中隐藏签名文件,因此要获取签名文件,必须在下载URL的末尾附加.asc

您可以下载该软件包,验证其签名,然后使用以下内容进行安装:

wget "$(pip download ci_release_publisher | grep 'http.*ci_release_publisher-'| awk '{print $NF}').asc"
gpg --no-default-keyring --keyring "$PWD/tmp_keyring.gpg" --recv-key '1D4E 9375 AD9B D50F 80FF  55AC 6F55 0977 4B1E F0C2'
gpg --no-default-keyring --keyring "$PWD/tmp_keyring.gpg" --verify ci_release_publisher-*.asc
# Read the output of the command above, you can't rely on its exit code as it's# 0, i.e. success, even if the key has expired or has been revoked
rm ci_release_publisher-*.asc
rm tmp_keyring.gpg
pip install --no-index --find-links "$PWD" ci_release_publisher-*

当然,这不会验证ci发行版正在使用的任何依赖项。

用法

安全考虑

在使用ci release publisher之前,必须考虑使用它所带来的安全隐患。

为了使用ci release publisher,必须创建一个新的github用户,使该用户成为要发布发布的存储库中的协作者,为该用户提供创建发布所需的存储库的写/推访问权限,为该用户生成一个访问令牌并将其存储在travis ci上的环境变量。所有这些都是必需的,以便ci发布者脚本能够使用github api验证用户身份,并在所需的存储库中创建发布。

问题是,如果访问令牌泄漏,有人可以使用它将代码推送到存储库中,删除/编辑问题注释,推送到pr分支中,用恶意二进制文件替换发布文件,等等——做各种讨厌的事情。Github在限制访问令牌的用途方面没有提供太多功能。

根据您愿意承担的安全风险,使用ci release publisher的方法主要有三种:

  • 发布到同一存储库

    这与travis ci的github发布部署的方式相同。特拉维斯ci sto使用对主存储库的完全写访问权限来恢复其访问令牌。这表示最大的安全风险,因为如果令牌泄漏,您的主存储库将面临风险。如果您已经将此类访问令牌用于其他Travis CI自动化,则您已经面临此风险。

  • 发布到其他存储库

    构建仍然在主存储库的travis ci上进行,但是构建工件被发布到不同的存储库。travis ci将访问令牌与对另一个存储库的完全写访问权一起存储。这大大降低了安全风险,因为如果访问令牌泄漏,只有其他存储库会受到影响,主存储库将是安全的。

  • 在不同的存储库中执行所有操作

    构建发生在存储库的travis ci上,而不是主存储库,并且构建工件被发布到同一个其他存储库中。整个过程独立于主存储库,可用于设置其他项目的个人构建。这比发布到另一个存储库的风险更低,因为现在存储访问令牌的是另一个存储库的travis ci,您应该能够将访问限制为比主存储库的travis ci更好。但是,由于构建发生在其他存储库的travis ci中,它不知道git push事件何时发生在主存储库中,因此您将无法构建到主存储库的每个git push,而是必须使用travis ci的cron作业每天运行一次构建。

下面是一张表格,总结了发布的三种方法:

<表><广告>< T/>同一回购协议 不同回购分开 < /广告><正文>主回购访问令牌权限写入阅读阅读不同的回购访问令牌权限 -写入写入存储在travis ci中的访问令牌 主回购主回购不同回购在travis ci上产生伪影主回购主回购不同回购每次主回购推送都可以释放 >是 >是<不< < > >

发布到同一存储库

  1. 创建一个新的github用户,该用户将仅用于创建版本。出于安全原因,我们建议您为要设置版本的每个存储库创建一个单独的用户。

  2. 在该用户下,如果使用travis ci.com,则使用repo访问检查,或者使用travis ci.org,则仅使用公共回购检查访问检查,则创建新的个人访问令牌。

  3. 在travis ci存储库的"设置"页上,例如在"环境变量"下的"https://travis-ci.org/nurupo/ci-release-publisher/settings" rel="nofollow">https://travis ci.org/nurupo/ci release publisher/settings,添加一个名为github_access_token的新环境变量,并将从github获得的访问令牌作为值。添加时确保未选中"在生成日志中显示值"。如果您已经使用github\u access\u令牌进行其他操作,则可以将变量命名为cirp\u github\u access\u令牌

  4. 邀请用户作为协作者访问存储库,以便用户对存储库具有写访问权限,即可以将其推入存储库。

  5. 接受邀请作为新用户。

  6. 作为新用户,登录travis ci,这将提示您授权travis ci访问您的github信息—接受它。

  7. 确保新用户可以使用b访问travis ci页为存储库生成详细信息。


    建议为每个存储库创建一个新用户,因为当存储在travis ci环境变量中的github访问令牌被泄漏,这实际上等于访问令牌所属的用户帐户被破坏,因为攻击者可以将代码、发布版本等推送到用户可以访问的所有存储库中。为每个存储库创建一个用户有助于限制api密钥泄漏时可能造成的损坏。但是,请注意,github tos允许您只有一个"机器帐户",创建更多的帐户在技术上违反tos,并且应该由您自己承担风险。为了更大程度地减少损害,将github存储库设置为不允许强制推送所有分支,要求所有更改在合并之前通过prs,并要求prs由其他贡献者审查,这样就不太可能有人偷偷摸摸地更改恶意代码在存储库中,如果访问令牌被破坏。


  8. .travis.yml中,识别产生工件的作业。

    在所有工件生成作业的脚本部分的末尾添加:

    -.travis/cirp/cleanup1.sh-.travis/cirp/store.sh "$TRAVIS_BUILD_DIR/artifacts"-.travis/cirp/cleanup2.sh

    其中,$travis_build_dir/artifacts是可以找到工件的路径。这将把工件存储在一个临时的存储版本中。我们会将它们下载回来,并在稍后的版本发布阶段删除这些临时存储发行版。

    现在确定工件产生阶段。如果一个阶段包含至少一个工件生产作业,我们称之为工件生产阶段。它可以包含其他不产生工件的作业。您可以拥有任意数量的工件生产阶段,也可以拥有任意数量的在它们之前、之后和中间不生产工件的阶段。

    在处于工件生成阶段但实际不生成工件的所有作业的脚本部分的末尾,添加:

    -.travis/cirp/cleanup1.sh-.travis/cirp/cleanup2.sh

    这将在生成失败时删除临时存储版本,以便它们不会在您的发布页面上乱扔杂物。

    找到最后一个神器制造阶段。如果之后有任何阶段,则可以选择要将发布作业添加到其中的任何阶段。如果之后没有任何阶段,则可以创建包含发布作业的发布阶段。在整个构建中只能有一个发布作业,它必须位于所有生成工件的作业之后,与生成工件的作业处于不同的阶段。不应将发布作业与生成工件的作业放在同一阶段。您的发布工作应该如下所示:

    if:type != pull_requestscript:-export ARTIFACTS_DIR="$(mktemp -d)"-.travis/cirp/collect.sh "$ARTIFACTS_DIR"-.travis/cirp/cleanup4.sh-.travis/cirp/publish.sh "$ARTIFACTS_DIR"-.travis/cirp/cleanup5.sh

    其中,$artifacts\u dir是从临时存储版本下载工件的路径。

    现在确定第一个工件生成阶段和发布阶段(如果有的话)之间不生成工件的所有阶段。在这些作业的脚本部分的末尾添加以下内容:

    -.travis/cirp/cleanup3.sh

    这将在生成失败时删除临时存储版本,以便它们不会在您的发布页面上乱扔杂物。

    您应该将以下内容添加到.travis.yml中,以避免travis ci构建github将要创建的标记,因为ci release publisher正在创建非草稿版本:

    branches:except:-# Do not run Travis-CI builds on tags CI Release Publisher creates as it-# will lead to endless (recursive?) tag creation and Travis-CI running-/^ci-.+$/

    下面是遵循这些说明之前的示例.travis.yml是省略的部分,并且env用于对作业进行注释。这是一个相当广泛的例子,有很多阶段和工作,希望能涵盖大多数情况。

    python setup.py install
    
    0 首先,让我们来确定产生工件的作业。这是工作3和5。

    我们将在作业3和5的脚本部分的末尾添加以下内容:

    -.travis/cirp/cleanup1.sh-.travis/cirp/store.sh "$TRAVIS_BUILD_DIR/artifacts"-.travis/cirp/cleanup2.sh

    由于作业3和5是产生工件的作业,这意味着它们所处的阶段(阶段2和阶段4)是产生工件的阶段。

    我们将在阶段2和阶段4的所有作业(不是作业3和5,即作业2和6)的脚本部分的末尾添加以下内容:

    -.travis/cirp/cleanup1.sh-.travis/cirp/cleanup2.sh

    由于阶段4是最后一个工件生成阶段,我们可以将发布作业添加到它之后的任何阶段(阶段5、6或7),或者创建一个新的发布阶段,例如阶段8。为了示例起见,假设我们要将发布作业添加到第6阶段。

    我们将在现有阶段6中添加以下作业:

    python setup.py install
    
    3

    由于阶段2是第一个工件生产阶段,阶段6是发布阶段,因此它们之间只有两个阶段不是工件生产阶段,即阶段3和阶段5。

    我们将在阶段3和阶段5的所有作业(即作业4和7)的脚本部分添加以下内容:

    -.travis/cirp/cleanup3.sh

    现在只需添加分支异常,我们就完成了:

    branches:except:-# Do not run Travis-CI builds on tags CI Release Publisher creates as it-# will lead to endless (recursive?) tag creation and Travis-CI running-/^ci-.+$/

    如果按照说明操作,我们的.travis.yml将更改为:

    python setup.py install
    
    6

    .travis/cirp/*.sh是帮助脚本,您可以在脚本目录中找到它们。

  9. 一般注意事项。

    < DOS:< /P>
    • 请使用.travis/cirp/*.sh帮助脚本,在安装并调用ci发行版的所有依赖项之前,它们会检查是否满足一些重要的先决条件。
    • 请修改publish.shscript以使用所需参数调用publish命令。
    • collect.shpublish.sh调用之间运行。例如,计算工件的散列并将其作为文件包含在工件目录中,以便上载,或者修改publish.sh以计算散列并将其作为release body文本参数传递,或者生成一个变更日志并将其设置为发布正文文本。
    • 请修改store.sh脚本,用所需参数调用store命令。
    • 请根据需要修改install.sh
    • 请根据您的需要修改check_precondition.sh
    • 请使用travis ci的allow_failures功能如果要允许生成工件的作业失败,则cleanup*.sh脚本将确保这些作业的生成工件不包含在版本中。
    • 如果您已经使用以ci-\ci-开头的分支名称或标记名称来执行其他操作,请在所有*.sh脚本中的所有python脚本调用上设置--tag prefix,因为ci release publisher可能会删除它们。
    • 如果所有脚本中的所有python脚本调用的分支或标记都与起始的/code>不同(例如<;name>;<;name>;),请在这些脚本中设置--tag prefix incomplete releases,因为ci发行商可能会删除它们。

    不要:

    • 不要修改cleanup*.sh脚本,尤其是传递给cleanup命令的参数。它们正是您要用以调用cleanup命令的参数,在不深入理解为什么需要它们的情况下更改它们很可能会导致中断。
    • 不要从travis.yml中删除cleanup*.sh调用。它们相当多,但是它们是为了尽量减少发布页面和草稿发布页面的混乱。另外,一些其他命令,如store,取决于要在它们之前调用的确切的cleanup命令,如果清除操作被删除,则会出现错误行为。
    • 别这样-排列调用*.sh脚本的顺序,这样做将破坏逻辑。
  10. < > >

    发布到其他存储库

    1. 按照发布到同一存储库中的所有步骤进行操作,但在步骤3中将访问令牌添加到主存储库的travis ci,并在步骤4中将新用户邀请到不同的非主存储库中。

    2. 除了步骤8中所做的.travis.yml修改之外,您还应该在调用ci release publisher之前设置cirp_github_repo_slug环境变量,告诉它应该将版本发布到其他存储库。cirp_github_repo_slug应设置为<;github user or org name>;/<;repo name>;,即删除了"https://github.com/" rel="nofollow">https://github.com/"的存储库url部分,例如,对于https://github.com/nurupo/ci release publisher这将是nurupo/ci release publisher。由于每次运行ci release publisher时都需要对其进行设置,因此更容易对其进行全局设置,如下所示:

      python setup.py install
      
      7
    3. 确保要发布发布到的github存储库至少有一个提交,因为github发布只是git标记之上的构造,没有任何提交就不能有git标记。

    4. < > >

      与发布到同一存储库不同,ci release publisher在发布到另一个存储库则为空,这意味着将使用引用github rpository的默认分支的标记来创建版本。之所以这样做是因为如果您将target\u commitish设置为$travis\u commit,这是刚刚推送到主存储库的提交,而且这种提交不存在于不同的存储库中——Github API会出错,因为它无法为不存在的提交创建标记。公平的假设是,不同的存储库不会更新刚刚推送到主存储库的内容。您可以通过向ci release publisher的storepublish命令提供--*target commitish参数来覆盖此行为。

      在不同的存储库中执行所有操作

      这里的想法是在一个不同的存储库中设置一个travis ci cron构建来运行daily/weekly/monthly,它将git pull主存储库的一个分支,修改我们刚刚提取的存储库的.travis.yml,以便它使用ci release publisher创建构建工件并将其发布到当前存储库中,然后将其全部推送到不同存储库的某个分支中。推送的行为将启动另一个travis ci构建,这次将发布版本。我们不想在cron构建中发布版本,因为如果有几个工件生成作业,每个作业在主存储库上执行git pull,在我们的构建运行时,主存储库可能会得到新的提交,这会导致一些作业拉取旧的历史记录,而另一个拉取新的历史记录,因此生成的构建工件可能具有不同的提交。通过将cron构建中的主存储库拉入另一个存储库的分支,我们保证所有作业都将在主存储库的同一版本上工作。

      1. 按照发布到同一存储库中的步骤1-7,存储访问令牌进入不同存储库的travis ci并邀请新用户访问不同存储库。

      2. 按照第8步和第9步创建.travis.build.yml文件,我们将用它替换主存储库的.travis.yml

      3. 创建.travis.yml并使用:

        python setup.py install
        
        8

        适当修改环境变量。

        我们使用travis ci的缓存功能来存储我们为其发布的最新提交的哈希值,这样,如果主存储库中没有任何更改,我们下次就不会创建新的版本。当然,在某些情况下,即使主存储库中没有任何更改,您仍希望创建新版本,例如,当其中一个依赖项更新时,例如openssl,但这超出了本示例的范围,您可以扩展此缓存解决方案来涵盖它。

        请注意,对于开放源代码项目(私有项目更长),travis ci的缓存expiers将在28天内缓存过期" rel="nofollow">travis ci的缓存expiers,而travis ci的每月cron构建之间的时间间隔未指定。travis ci运行cron构建的确切时间被记录为实现定义,因此travis ci可以随时更改它,但基于一些观察结果,目前,它运行每月cron构建的日期和时间似乎与运行第一个每月cron作业的日期和时间完全相同,但随着月份的增加,例如2019-02-19 09:00:00->;2019-03-19 09:00:00->;2019-04-19 09:00:00->;2019-05-19 09:00:00。如果是这样的话,那么自上次运行以来至少会过去28天,这意味着缓存总是在下一个每月cron构建运行时过期,因此您可能无法从每月cron构建中使用缓存中获益。

      4. 创建一个update_branch.sh文件,将其标记为可执行文件,并使用如下内容(您可能需要自定义此文件):

        python setup.py install
        
        9

        如果使用后者,请将$github_access_token更改为$cirp_github_access_token,如果主存储库是私有的,请将访问令牌包含到git remote add upstream命令的url中,否则我们将无法克隆它。将new user s email@example.com更改为新用户的电子邮件地址,并将new users name更改为新用户的名称。删除所有可能使用>;/dev/null 2>;&;1泄漏访问令牌的命令的输出,并确保不会在任何地方公开.git/config,因为其中存储了所有具有访问令牌的远程URL。travis ci有关于如何避免泄漏机密以生成日志的最佳做法的文档,介绍了防止访问令牌泄漏以生成日志的最佳做法。

        请注意,这个简单的update_branch.sh脚本不会为在主存储库中创建的任何标记创建发行版,但您可以展开它来执行此操作。

      5. 根据您的需要修改.travis.ymlupdate_branch.sh

      6. .travis.ymlupdate_branch.sh.travis.build.yml推送到不同的存储库中。

      7. 推送之后,确保在travis ci上创建了构建,并成功创建了另一个构建,该构建成功并创建了发行版。

      8. 转到travis ci上存储库的"设置"页,例如https://travis-ci.org/nurupo/ci-release-publisher/settings" rel="nofollow">https://travis ci.org/nurupo/ci release publisher/settings,并在"cron jobs"下将其设置为运行将文件推送到的分支的cron构建。每日、每周或每月。

      9. < > >

        命令行参数

        它通常是有用的要在安装程序之前知道程序提供了哪些选项,下面是所有可用的命令行参数。

        请注意,ci release publisher使用$travis\u环境变量来知道它在哪个分支上运行,是否推送了标记等等,因此,在指定ci release publisher已经可以从$travis\u环境变量中获得的内容时,不会看到命令行参数。

        <详情>CI发行者--版本
        pip install ci_release_publisher
        
        0 <详细内容><详情>CI发行者--帮助
        pip install ci_release_publisher
        
        1 <详细内容><详情>CI发行者商店--帮助
        pip install ci_release_publisher
        
        2 <详细内容><详情>ci release publisher cleanup\u store--帮助
        pip install ci_release_publisher
        
        3 <详细内容><详情>CI发行者收藏--帮助
        pip install ci_release_publisher
        
        4 <详细内容><详情>CI发行者发布--帮助
        pip install ci_release_publisher
        
        5 <详细内容><详情>ci release publisher cleanup\u发布--帮助
        pip install ci_release_publisher
        
        6 <详细内容>

        故障排除

        为了防止github访问令牌泄漏,ci release publisher捕获所有异常并仅打印出异常类型和消息,从而避免打印出堆栈跟踪,因为访问令牌通常作为函数参数传递,并可能显示在堆栈跟踪中。虽然这是一个很好的安全措施,但也意味着您不知道异常究竟来自何处。幸运的是,当错误地使用ci发布服务器时,只会出现一些常见的异常,其中大多数都与对github或travis ci使用错误的api端点、错误的github访问令牌或权限设置不足的访问令牌有关。本节试图根据异常类型和消息记录这些异常。

        jsondecodeerror

        如果您得到:

        pip install ci_release_publisher
        
        7

        很可能travis ci无法使用提供的github访问令牌对ci发布服务器进行身份验证。确保在访问令牌上设置了正确的作用域,例如.com上的travis ci的repo.org上的travis ci的public_repo,并且您作为您正在使用其访问令牌的github用户至少登录了travis ci web界面一次,授权travis ci访问该用户的github帐户,以便travis ci为github用户创建一个帐户。

        如果您可以在您的计算机上本地访问$github\u access\u令牌,则可以使用此curl命令使用github access令牌测试travis ci身份验证:

        pip install ci_release_publisher
        
        8

        您希望在回复中看到2xx http代码和travis ci访问令牌作为有效负载。再次,请在本地运行,不要在travis ci上运行它,因为它可能会显示$github_access_token,并且它会在成功时显示您的travis ci access token。

        badCredentialsException

        如果您得到:

        pip install ci_release_publisher
        
        9

        这意味着您提供的github访问令牌没有足够的权限在目标github存储库中创建版本。请确保您已邀请新用户访问存储库,新用户已接受邀请,并已授予他们对该邀请的完全写入权限。

        许可证

        麻省理工学院< /P>

        欢迎加入QQ群-->: 979659372 Python中文网_新手群

        推荐PyPI第三方库


热门话题
java mahout创建带有首选项的基于项目的推荐程序   java Maven:过滤任何资源   swing为什么Java中的侦听器相互依赖?   java在TextView中显示json响应   drjava从txt文件中检索一个随机字,但没有得到任何输出,也没有编译错误   JWindow上的java JPanel,添加组件   安卓使用jcocoa将ios代码转换为java   除非调整帧的大小,否则java动画不起作用   从java代码创建Json文件   java使用jdom向现有xml添加内容   如何在java中设置socket写超时?   java将值拆分为两个随机数