0%

Github_Action

Overview

Github Action是持续集成/交付(CI/CD)的平台,允许开发者自动化构建测试部署项目。Github Action不仅仅是DevOps,还允许在远程仓库发生其他事件时运行工作流程。Github Action提供Ubuntu\Windows\MacOS虚拟机来运行工作流程,同时也允许开发者使用自己的数据中心服务器或云服务器来自托管运行器

Workflow

在Github Action中使用yaml文件进行配置,一个.yml文件代表一个工作流,该配置文件均放置于项目路径.github/workflows下。在持续集成中,一系列操作如拉取代码运行测试远程登录服务器项目部署等称为Action。在Github中有官方提供的开源Action脚本可以直接引用,比如官方市场awesome actions

在Github Action的工作流配置文件中存在以下概念

  • workflow: 工作流程,一般一个yaml文件代表一个工作流程
  • job: 一个工作流程由多个jobs构成
  • step: 一个jobs中会有多个steps串行执行,每个steps由无序列表符号-起头
  • action: 在一个steps中可以采取Github的action库中的脚本,依次执行一个或多个命令

以下将以pytorch中的try-merge.yml工作流配置文件作为样例进行语法学习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
name: Validate and merge PR # 定义工作流名称

on: # 定义工作流触发条件
repository_dispatch:
types: [try-merge]

jobs: # 定义workflow中的多个jobs
do_merge: # 定义第一个jobs,名称为do_merge
name: try_merge_pr_${{ github.event.client_payload.pr_num }} # 定义该job的可视化名称,在github action页面中显示
runs-on: linux.20_04.4x # 定义该jobs的运行环境
environment: mergebot
permissions:
id-token: write
env:
GH_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
steps: # 定义一个jobs中的多个steps
- name: Checkout repo # step1 Checkout
id: checkout
uses: actions/checkout@v3 # 使用actions仓库中提供的checkout脚本,版本v3
with: # with用于向第三方action提供键值对形式的参数
fetch-depth: 0
token: ${{ secrets.MERGEBOT_TOKEN }}

- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.8'
check-latest: false
cache: pip
architecture: x64
- run: pip install pyyaml==6.0 rockset==1.0.3

- name: Setup committer id
run: | # run: |在yaml格式中表示多行文本标识符
git config --global user.email "pytorchmergebot@users.noreply.github.com"
git config --global user.name "PyTorch MergeBot"
- name: Merge PR
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.MERGEBOT_TOKEN }}
PR_NUM: ${{ github.event.client_payload.pr_num }}
FORCE: ${{ github.event.client_payload.force}}
COMMENT_ID: ${{ github.event.client_payload.comment_id }}
REBASE: ${{ github.event.client_payload.rebase }}
IGNORE_CURRENT: ${{ github.event.client_payload.ignore_current }}
ROCKSET_API_KEY: ${{ secrets.ROCKSET_API_KEY }}
DRCI_BOT_KEY: ${{ secrets.DRCI_BOT_KEY }}
GITHUB_RUN_ID: ${{ github.run_id }}
run: |
set -x # set -x表示在shell启动调试模式,在每一步命令运行之前输出相应命令
if [ -n "${REBASE}" ]; then
# attempt to rebase, if it fails then comment on the PR that it failed
if ! python3 .github/scripts/tryrebase.py "${PR_NUM}" --branch "${REBASE}"; then
python3 .github/scripts/comment_on_pr.py "${PR_NUM}" "merge"
exit 0
fi
git checkout main
git fetch -p
# give github some time between the push and start workflows so that Github's messages
# on the PR appear in chronological order (timing issues can shuffle them around)
sleep 60
fi
if [ -n "${FORCE}" ]; then
if [ -n "${COMMENT_ID}" ]; then
python3 .github/scripts/trymerge.py --force --comment-id "${COMMENT_ID}" "${PR_NUM}"
else
python3 .github/scripts/trymerge.py --force "${PR_NUM}"
fi
elif [ -n "${IGNORE_CURRENT}" ]; then
if [ -n "${COMMENT_ID}" ]; then
python3 .github/scripts/trymerge.py --ignore-current --comment-id "${COMMENT_ID}" "${PR_NUM}"
else
python3 .github/scripts/trymerge.py --ignore-current "${PR_NUM}"
fi
elif [ -n "${COMMENT_ID}" ]; then
python3 .github/scripts/trymerge.py --comment-id "${COMMENT_ID}" "${PR_NUM}"
else
python3 .github/scripts/trymerge.py "${PR_NUM}"
fi
- name: Comment on Canceled
if: ${{ cancelled() && steps.checkout.outcome == 'success' }}
continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.MERGEBOT_TOKEN }}
PR_NUM: ${{ github.event.client_payload.pr_num }}
run: |
set -x
python3 .github/scripts/comment_on_pr.py "${PR_NUM}" "merge"

- name: configure aws credentials
uses: aws-actions/configure-aws-credentials@v3
continue-on-error: true
with:
role-to-assume: arn:aws:iam::308535385114:role/upload_to_ossci_raw_job_status
aws-region: us-east-1

- name: Upload merge record to s3
if: always()
continue-on-error: true
uses: seemethere/upload-artifact-s3@v5
with:
s3-bucket: ossci-raw-job-status
s3-prefix: merges/${{ github.repository }}/${{ github.event.client_payload.pr_num }}/${{ github.event.client_payload.comment_id }}/${{ github.run_id }}
path: merge_record.json

# We want newer merge commands to supercede old ones
concurrency:
group: try-merge-${{ github.event.client_payload.pr_num }}
cancel-in-progress: true

  • ${{...}}上下文变量,在Github Action脚本中,存在一些Github内置的上下文变量,在工作流执行时由Github官方服务器自动注入,用于提供访问仓库、运行时变量、安全信息等相关数据

  • concurrency字段用于控制工作流的并发执行,避免同一工作流在同一分支或特定工作流内执行多次。在上述示例中,并发事件按pr_num拉取请求分组,即每个PR都有自己的并发控制,当一个PR中有多个任务出发,则只有最新的被执行

  • 一个job的name字段旨在github action页面中运行时展示给观察者的名称,而job字段下的第一层工作名称就是在整个脚本中唯一区分一个job的名称