GitHub Actions 备忘
GitHub Actions 如何仅在某些文件发生更改时执行特定的 job, 给 GitHub Actions write contents 权限
GitHub Actions 如何仅在某些文件发生更改时执行特定的 job
要实现某些 job 仅在特定文件发生更改时执行,您可以在工作流中使用 if
语句来检查变更文件。这需要使用 actions/checkout
和 dorny/paths-filter
动作。下面是一个示例,仅在 my_folder
中的文件发生更改时才执行名为 run_job
的 job:
1name: Conditional Job Execution
2
3on: [push, pull_request]
4
5jobs:
6 check_changes:
7 runs-on: ubuntu-latest
8 outputs:
9 has_changes: ${{ steps.filter.outputs.has_changes }}
10
11 steps:
12 - name: Checkout repository
13 uses: actions/checkout@v2
14
15 - name: Check for changes in my_folder
16 uses: dorny/paths-filter@v2
17 id: filter
18 with:
19 filters: |
20 has_changes:
21 - 'my_folder/**'
22
23 run_job:
24 runs-on: ubuntu-latest
25 needs: check_changes
26 if: ${{ needs.check_changes.outputs.has_changes == 'true' }}
27
28 steps:
29 - name: Checkout repository
30 uses: actions/checkout@v2
31
32 - name: Run task only if my_folder files changed
33 run: echo "Files in my_folder have changed, running the task."
在这个示例中,我们首先创建一个名为 check_changes
的 job,使用 dorny/paths-filter
动作来检查是否有变更的文件。然后,我们将其输出设置为 has_changes
,并在 run_job
的 if
语句中使用该输出,如果 has_changes
为 true
,则执行 run_job
。这样,仅当 my_folder
中的文件发生更改时,run_job
才会执行。
默认 Actions 只有部分权限
Workflows have read permissions in the repository for the contents and packages scopes only.
使用 permissions.contents 字段增加写入权限,如下:
1name: 'GitHub CI'
2
3permissions:
4 contents: write
GitHub Actions run 命令如何换行?
GitHub Actions 中的 run
命令是用来执行 shell 命令的,你可以使用 shell 的语法来实现换行。这样,你可以在同一个 run
语句中执行多个命令。以下是一些示例:
使用多行字符串:
1steps:
2 - name: My first step
3 run: |
4 echo 'Hello, world!'
5 echo 'Another command'
6 echo 'And another'
使用分号 (;
):
1steps:
2 - name: My first step
3 run: echo 'Hello, world!'; echo 'Another command'; echo 'And another'
使用 &&
(如果你想要前一个命令成功时才运行下一个命令):
1steps:
2 - name: My first step
3 run: echo 'Hello, world!' && echo 'Another command' && echo 'And another'
上述的每个例子中,echo 'Hello, world!'
,echo 'Another command'
和 echo 'And another'
都被看作独立的命令,并且会按照它们出现的顺序被执行。
另外,注意在YAML中,如果你想在一行内包含多个命令,使用分号 (;
) 或 &&
是一种好方法。如果你想让你的代码更容易读,那么使用管道符 (|
) 来创建一个多行字符串可能是一个更好的选择。
分号(;) 和 && 的区别
在 shell 脚本和命令行中,分号 (;
) 和 &&
用来在同一行中运行多个命令,但它们之间存在一些关键的差异。
-
分号 (
;
):它允许你在同一行中运行多个命令,这些命令会按照从左到右的顺序依次执行,无论前一个命令是否成功执行。例如:
command1 ; command2 ; command3
。在这里,无论command1
是否成功,command2
都会执行,然后是command3
。 -
&&
:它也允许你在同一行中运行多个命令,但是后面的命令只有在前面的命令执行成功(返回值为0)时才会执行。例如:
command1 && command2 && command3
。在这里,如果command1
执行成功,那么command2
会被执行,如果command2
也成功,那么command3
会被执行。如果command1
或command2
失败(返回值非0),那么后面的命令将不会执行。
因此,你可以根据你的需求选择使用哪种方式来在一行中运行多个命令。如果你希望无论前一个命令是否成功,都执行所有的命令,那么使用分号 (;
)。如果你希望只有在前一个命令成功的情况下才执行下一个命令,那么使用 &&
。
在 GitHub Actions 环境使用 xsel
解决 Can't open display: (null)
报错:
如果你的程序需要在无头环境(比如 GitHub Actions)中运行并且需要访问 X11 显示服务(比如使用 xsel
访问剪贴板),你可以使用 Xvfb
(虚拟帧缓冲 X 服务器)作为替代方案。
Xvfb
是一个运行在内存中的显示服务器,用于运行图形应用程序,但不显示任何图形输出,这使得它非常适合在无头环境中使用。
你可以在 GitHub Actions 中安装并启动 Xvfb
,然后运行你的程序。以下是一个例子:
1name: Your Workflow
2
3on: [push, pull_request]
4
5jobs:
6 your-job:
7 runs-on: ubuntu-latest
8
9 steps:
10 - name: Checkout code
11 uses: actions/checkout@v2
12
13 - name: Install and run Xvfb
14 run: |
15 sudo apt-get install -y xvfb
16 Xvfb :99 &
17 export DISPLAY=:99
18
19 - name: Run your program
20 run: |
21 # Run your program here
在这个示例中,Xvfb :99 &
启动了一个新的 Xvfb
实例,并将其指定为显示编号 99。export DISPLAY=:99
将 DISPLAY 环境变量设置为这个 Xvfb
实例,这样,你的程序就会将其作为默认的 X 显示服务器。
注意每个步骤都是在单独的 shell 中执行的,不同步骤之间的环境变量不会共享
如果你使用的是 Xvfb
,你可能需要将 DISPLAY
设置为 Xvfb
服务的编号,比如 :99
:
1export DISPLAY=:99
然后,你就可以运行 xsel
命令,它会使用 DISPLAY
环境变量中指定的 X 显示服务器。
如果你在 GitHub Actions 环境中运行 xsel
,你可能需要在运行 xsel
命令的同一个步骤(step)中设置 DISPLAY
环境变量,因为每个步骤都是在单独的 shell 中执行的,不同步骤之间的环境变量不会共享。这就是为什么之前的示例中在运行程序前设置 DISPLAY
环境变量的原因。