简介
在本指南中,我们将了解什么是GitHub动作,它们是如何工作的,并使用Python构建一个工作流程,展示如何使用GitHub动作来自动化任务。
自 2008 年成立以来,GitHub 已经成长为开发项目托管领域事实上的领导者。一个以社区为导向的想法,让所有我们喜欢的开源程序在一个中心的地方免费托管,这个想法炸开了锅。GitHub变得如此流行,以至于它成了git ;你会发现网上有几十篇文章解释git与GitHub的不同,反之亦然。
在它的10周年纪念日,一家大公司以75亿美元收购了GitHub。那家公司的名字是微软。抛开GitHub的收购,建立WSL和拥有许多开源项目,如VS Code、.NET和TypeScript,仅举几例,微软改变了开发游戏和公众对该公司侵犯隐私的看法,即Windows 10。
尽管它仍然以社区为导向,但GitHub的下一个目标是开始赚取一些收入--通过进入企业领域。提示 -GitHub的行动。
看一看现有的企业解决方案
在微软入主GitHub的时候,企业级的软件开发领域已经有了一些大的参与者。
- Atlassian 的 BitBucket允许与 Jira 和 Trello(问题管理和组织的领导者)无缝集成。
- 亚马逊的CodeCommit允许使用AWS的组织不离开一个UI和一个CLI工具的舒适度。
- GitLab,以其面向DevOps的方法,旨在将整个开发过程集中在一个屋檐下。
在过去的几年里,GitHub设法增加了许多它的企业竞争功能,包括CI/CD
CI/CD和自动化
现代软件开发在很大程度上依赖于自动化,原因很简单--它能加快事情的进展。新版本被自动构建、测试并部署到适当的环境中。
只需要花点力气写几个脚本,配置几台机器来执行它们。GitHub 所提供的这些功能是以GitHub 动作的形式出现的。
GitHub 行动概述
在撰写本指南时,GitHub Actions 还不到两年时间。尽管它还很年轻,但由于它是GitHub 的一项功能,所以已经相当成熟了。
社区
无数的用户加入进来,开始了解 GitHub 动作的来龙去脉,并开始编写自己的可重用模块(或动作),与世界其他地方分享。GitHub在其营销模式中严重依赖这种贡献。目前,有超过9500个不同的动作,允许你在几行代码中设置你的环境,运行linters和测试器,与许多主要的平台API互动等。除了git 和你最喜欢的编辑器,所有这些都不需要安装任何软件。
工作流程
我们通过工作流来定义我们的自动化流程。它们是YAML文件,其中包含我们工作流程的名称、触发事件、工作和管道的步骤以及执行它们的运行器。
YAML
YAML Ain't a Markup Language或YAML(一个递归的缩写)是一种主要用于编写配置文件的语言。它通常比JSON更受欢迎,因为它更容易编写和可读性。尽管JSON在序列化方面更快,而且更严格,YAML还是被用于速度不是很重要的地方。
触发事件
on 关键字指定了一个或多个GitHub(注意:不仅仅是git)事件来触发工作流。事件可以很宽泛,比如每次推送到仓库,也可以很具体,比如每次拉动请求得到新的评论。
这些事件也可以用类似于cron的方式来安排。
name: my workflow
on:
push:
branches: [main, test]
这里,我们为每次推送到main 或test 分支设置了一个触发器事件。另一种注册触发器的方式是在一个时间表上,例如。
name: my nightly build workflow
on:
schedule:
cron: '0 22 * * *'
这是一个计划在每天10点进行的夜间构建。
工作
到目前为止,我们已经给我们的工作流起了一个名字,并配置了触发它的不同事件。jobs 关键字列出了将被执行的行动。一个工作流程可以容纳多个作业,每个作业有多个steps 。
jobs:
job1:
steps:
.
.
job2:
steps:
.
.
默认情况下,所有作业都是并行运行的,但我们可以使用needs 关键字让一个作业等待另一个作业的执行。
jobs:
job1:
steps:
.
.
job2:
needs: job1
steps:
.
.
job3:
needs: [job1, job2]
steps:
.
.
确保作业逐一成功执行。
我们还可以独立配置每个作业的环境,或者使用matrix strategy ,在多个配置中运行一个作业。 文档指出。
矩阵允许你通过在一个作业定义中执行变量替换来创建多个作业。
下面是一个矩阵构建的例子,它被配置为在多个平台上工作。
jobs:
ubuntu_job:
runs-on: ubuntu-latest
steps:
.
.
multi_os_job:
runs-on: {{matrix.os}}
strategy:
matrix:
os: [ubuntu-latest, windows-2016, macos-latest ]
steps:
.
.
行动
行动是可重复使用的模块,可以像其他工作或步骤一样放在工作流程中。它们既可以接受输入也可以产生输出。社区市场上有很多用于准备环境的引导动作;我们今天将使用几个。
你可以把你自己的动作写成docker容器或者使用vanilla JavaScript,然后贡献给市场,或者留给自己。
一个动作可以很容易地在工作流程中被引用,就像列表中的任何其他步骤一样。
jobs:
compile_code:
runs-on: ubuntu-latest
steps:
- name: check out repo
uses: actions/checkout@v2
- name: compile code
run: gcc main.c
.
.
这里,我们可以看到一个像其他步骤一样使用行动的例子。注意,与工作不同,步骤总是连续执行的。
运行者
运行器,也被称为代理或工人,是负责执行工作流的机器。每个运行器可以有不同的设置。例如,GitHub 提供了三种最流行的操作系统的运行器 - Ubuntu、Windows 和 MacOS。
GitHub提供自己的运行器,但你也可以选择用GitHub Actions运行器应用程序来托管自己的运行器。
价格
如果仓库是公开的,并且每月的门槛不超过2000分钟,GitHub运行程序可以免费执行工作流程。
工件 - 工作流持久化数据
由于GitHub的运行人员是暂时可用的,所以他们处理和生成的数据也是如此。Artifacts是在运行程序执行后可以在仓库页面上保留的数据,需要通过特殊的upload-artifact 操作上传。
默认的保留时间段是90天,但也可以改变。

概览屏幕上有很多数据迎接我们,包括工作流运行的编号、所有排队执行或已经执行的作业列表、不同作业及其连接的可视化表示,以及工作流产生的任何工件。
实践中的GitHub行动 - 一个Python基准测试器
**注意:**这个例子使用了为本文创建的仓库,不出所料,它可以在GitHub上找到。
让我们把我们所学到的东西整合成一个完整的工作流程。我们将创建一个Python基准测试器工作流,放在.github/workflows/benchmark.yml 。
该工作流将在每次推送到主分支时被触发。
name: python version benchmarker
on:
push:
branches: [main]
该工作流由三个阶段组成。
提示阶段
第一个工作的任务是对benchmarker.py 的内容进行润色,确保它的分数至少为8.0。
jobs:
pylint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2 # checkout repo
- uses: actions/setup-python@v2 # set up environment for python
with:
python-version: 3.7
- uses: py-actions/py-dependency-install@v2 # install dependencies from requirements.txt
with:
path: requirements.txt
- name: run pylint, fail under 8.5
run: pip install pylint; pylint benchmarker.py --fail-under=8
基准测试
我们将在6个不同的python版本和实现中运行该基准,如果代码与所有的版本和实现不兼容就会失败(通过矩阵策略的fail-fast 参数配置,默认为true )。
benchmark:
runs-on: ubuntu-latest
needs: pylint
outputs:
pypy2: ${{ steps.result.outputs.pypy2 }}
pypy3: ${{ steps.result.outputs.pypy3 }}
py2-7: ${{ steps.result.outputs.py2-7 }}
py3-6: ${{ steps.result.outputs.py3-6 }}
py3-7: ${{ steps.result.outputs.py3-7 }}
py3-8: ${{ steps.result.outputs.py3-8 }}
strategy:
matrix:
include:
- python-version: pypy2
out: pypy2
- python-version: pypy3
out: pypy3
- python-version: 2.7
out: py2-7
- python-version: 3.6
out: py3-6
- python-version: 3.7
out: py3-7
- python-version: 3.8
out: py3-8
steps:
- uses: actions/checkout@v2
- name: setup py
uses: actions/setup-python@v2
with:
python-version: ${{matrix.python-version}}
- name: save benchmark stats
id: result
run: |
echo "::set-output name=${{matrix.out}}::$(python benchmarker.py)"
让我们更详细地看看这个问题,看看你在使用GitHub Actions时可能遇到的一些细微问题。outputs 关键字指定了一个工作可以产生并允许其他工作引用的key:value 对。key 的值是输出的名称,而value 是对具有指定id 的步骤的特定输出的引用。
在我们的例子中,带有id: result 的步骤将产生一个基于矩阵'值的输出,python-version 必须被修改并提供给out 参数,因为GitHub的对象访问语法不允许在对象名称中使用点,以及在第一个位置有数字。
没有固有的方法可以将输出放在一个json中,并将steps.result.outputs 作为一个JSON对象来引用--这可以用于只读目的,我们将在下一阶段看到。每个输出都必须明确定义。
上传至Pastebin并创建一个新的工件
第三也是最后一个阶段将读取前一阶段的输出并将其编译成一个文件。该文件将作为一个工件被上传,同时也被上传到pastebin。
为了向pastebin发出post 请求,我们需要配置一个账户,然后使用其API密钥。
pastebin:
runs-on: ubuntu-latest
needs: benchmark
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.9
- uses: py-actions/py-dependency-install@v2
with:
path: requirements.txt
- name: use benchmark data
run: echo '${{ toJSON(needs.benchmark.outputs) }}' > matrix-outputs.json
- name: pastebin API request
env:
PASTEBIN_API_KEY: ${{ secrets.PASTEBIN_API_KEY }}
run: python pastebin.py
- name: upload newly created artifact
uses: actions/upload-artifact@v2
with:
name: benchmark-stats
path: newpaste.txt
秘密被放置在作业的环境变量中,以便在Python中用os.environ[PASTEBIN_API_KEY] ,方便访问。
GitHub中的秘密管理
GitHub 为仓库或项目范围内的秘密提供了一个安全的地方。要保存一个秘密,请浏览仓库设置,并在秘密标签中添加一个新值。

什么时候不选择GitHub Actions作为CI/CD工具?
尽管我们已经看到了GitHub这个新功能的潜力,但还是有一些事情需要考虑;这些事情可能会成为障碍,让你在其他地方寻找自动化工具。
- GitHub提供的运行器是相当缺乏的。2个核心和8GB的内存,它们适合运行linters和测试;但不要想一些严肃的编译工作。
- REWRITE 工作流调试可能是一个令人不快的经历。没有办法重新运行一个作业,只能重新运行整个工作流程。如果最后一步遇到了问题,你要么重写工作流,使故障排除更容易忍受,要么等整个工作流运行完后再去找你的故障排除点。
- 不支持分布式构建。
总结
在过去的几年里,GitHub Actions已经成熟了很多,但还不够。不过,潜力还是有的。拥有所有git平台中最好的API,以及用JavaScript编写动作的创新方法,所有这些都得到了世界上最大的git社区的支持--毫无疑问,GitHub Actions有潜力接管整个CI/CD游戏。但现在还不行。
目前,当企业仍然依赖Jenkins、Travis CI和GitLab CI等工具时,请使用这个工具进行简单的编译/打包,或为你的提交添加标签。
