通常,我在.gitlab-ci.yml
中执行以下作业,以通过SSH在远程服务器上执行命令:
# The job
deploy:
script:
# I've omitted the SSH setup here
- |
ssh gitlab@example.com "
# Makes the server print the executed commands to stdout. Otherwise only the command output is printed. Required for monitoring and debug.
set -x &&
# Executes some commands
cd /var/www/example &&
command1 &&
command2 &&
command3 &&
command4 &&
command5
"
它可以正常工作,但是YAML代码看起来太复杂了:
set -x
命令比有用的代码更像样板。普通CI命令不需要它,因为GitLab CI会自动打印它们。&&
也是样板。当命令之一失败时,它们使执行停止。否则,当一个命令失败时,将执行下一个命令(与普通的作业命令相反)。在没有上述缺点的情况下,是否有更清晰便捷的方法可以通过SSH在远程计算机上执行多个命令?
我不想使用Ansible这样的外部部署工具来使CD配置尽可能简单(欢迎使用默认的POSIX / Linux命令)。我也考虑过在单独的ssh
调用中运行每个命令,但是由于建立了多个SSH连接,我担心这样做可能会增加作业执行时间(但我不确定):
deploy:
script:
- ssh gitlab@example.com "cd /var/www/example"
- ssh gitlab@example.com "command1"
- ssh gitlab@example.com "command2"
# ...
答案 0 :(得分:2)
将命令保留在没有set -x
和&&
的单独文件 remote.sh 中:
#!/usr/bin/env bash
# Executes some commands
cd /var/www/example
command1
command2
command3
command4
command5
并使用eval
在远程服务器上运行它们:
deploy:
script:
- ssh gitlab@example.com "eval '$(cat ./remote.sh)'"
这种方法将使YAML简单,干净并满足您的所有要求。
答案 1 :(得分:0)
一种更简洁明了的方法是使用set -e
。当其中一个命令失败时,它将使整个脚本失败。它使您不必在每一行上都使用&&
:
# The job
deploy:
script:
# I've omitted the SSH setup here
- |
ssh gitlab@example.com "
# Makes the server print the executed commands to stdout. Makes the execution stop when one of the commands fails.
set -x -e
# Executes some commands
cd /var/www/example
command1
command2
command3
command4
command5
# Even complex commands
if [ -f ./.env ]
then command6
else
echo 'Environment is not set up'
exit 1
fi
"