Gitlab CI 在拉取原点之前检查目录是否存在

Dev*_*rog 4 bash gitlab gitlab-ci-runner

我正在尝试使用 gitlab ci runner 将我的 Flask 应用程序部署到 AWS EC2 实例。

.gitlab.ci.yml

stages:
  - test
  - deploy

test_app:
  image: python:latest
  stage: test
  before_script:
  - python -V
  - pip install virtualenv
  - virtualenv env
  - source env/bin/activate
  - pip install flask
  script:
  - cd flask-ci-cd
  - python test.py

prod-deploy:
  stage: deploy
  only:
    - master # Run this job only on  changes for stage branch

  before_script:
    - mkdir -p ~/.ssh
    - echo -e "$RSA_KEY" > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'

  script:
    - bash .gitlab-deploy-prod.sh

  environment:
    name: deploy
Run Code Online (Sandbox Code Playgroud)

.gitlab-deploy-prod.sh

stages:
  - test
  - deploy

test_app:
  image: python:latest
  stage: test
  before_script:
  - python -V
  - pip install virtualenv
  - virtualenv env
  - source env/bin/activate
  - pip install flask
  script:
  - cd flask-ci-cd
  - python test.py

prod-deploy:
  stage: deploy
  only:
    - master # Run this job only on  changes for stage branch

  before_script:
    - mkdir -p ~/.ssh
    - echo -e "$RSA_KEY" > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'

  script:
    - bash .gitlab-deploy-prod.sh

  environment:
    name: deploy
Run Code Online (Sandbox Code Playgroud)

错误:.gitlab-deploy-prod.sh:第 7 行:-o:找不到命令

我如何检查目录是否存在?

我尝试过的。

#!/bin/bash

# Get servers list
set -f

# access server terminal
shell="ssh -o StrictHostKeyChecking=no ${SERVER_URL}"
git_token=$DEPLOY_TOKEN

echo "Deploy project on server ${SERVER_URL}"
if [ ${shell} -d "/flask-ci-cd" ] # check if directory exists
then
   eval "${shell} cd flask-ci-cd && git clone https://sbhusal123:${git_token}@gitlab.com/sbhusal123/flask-ci-cd.git master && cd flask-ci-cd"
else
    eval "${shell} git pull https://sbhusal123:${git_token}@gitlab.com/sbhusal123/flask-ci-cd.git master && cd flask-ci-cd && cd flask-ci-cd"
fi
Run Code Online (Sandbox Code Playgroud)

我尝试在执行 if else 内的脚本之前登录 ssh shell。但它并没有按照预期的方式工作。

Kam*_*Cuk 5

  1. 您的脚本有一些错误。
  2. 不要使用评估。不,eval 不是这样工作的。评估是邪恶的
  3. 将命令存储到变量时,不要使用普通变量。使用 bash 数组来保存“单词”。
  4. 通过 ssh 传递的命令是双重转义的。我建议更喜欢使用此处的文档,它们更容易正确引用。请注意这里文档分隔符是否被引用时扩展的差异。
  5. i thought gitlab would provide me with shell access不,如果没有打开标准输入,远程 shell 将终止,因为它将从输入中读取 EOF。不,事情不是这样的。
  6. 无需进行多次远程连接,只需将执行转移到远程端一次并在那里完成所有工作。
  7. 花点时间研究一下shell 中的引用分词是如何工作的。
  8. git_token=$DEPLOY_TOKEN不,设置的变量不会导出到远程 shell。在调用远程端之前手动传递它们或扩展它们。(或者你也可以使用ssh -o SendEnv=git_token和配置远程 ssh,AcceptEnv=git_token我认为,从未尝试过)。
  9. 阅读您使用的实用程序的文档。
  10. 不,git cloneurl 后面不带分支名称。您可以使用--branch-b选项指定分支。url 之后是目录名称。看git clone --help。对于 也一样git pull

我如何检查目录是否存在?

使用 bash 数组来存储命令。test只需在远程端执行命令即可检查该目录是否存在。

shell=(ssh -o StrictHostKeyChecking=no "${SERVER_URL}")
if "${shell[@]}" [ -d "/flask-ci-cd" ]; then
     ...
Run Code Online (Sandbox Code Playgroud)

如果目录名称带有空格,我会选择:

if "${shell[@]}" sh <<'EOF'
[ -d "/directory with spaces" ]
EOF
then
Run Code Online (Sandbox Code Playgroud)

转到set -x查看sh远程端也发生了什么。

对于您的脚本,请尝试将执行移至远程端 - 建立 3 个单独的连接几乎没有逻辑。我说只是

echo "Deploy project on server ${SERVER_URL}"
ssh -o StrictHostKeyChecking=no "${SERVER_URL}" bash <<EOF
if [ ! -d /flask-ci-cd ]; then
     # Note: git_token is expanded on host side
     git clone https://sbhusal123:${git_token}@gitlab.com/sbhusal123/flask-ci-cd.git /flask-ci-cd
fi
cd /flask-ci-cd
git pull
EOF
Run Code Online (Sandbox Code Playgroud)

但是,在某些情况下,不要正确引用,而是使用declare -pdeclare -f将正确引用的内容传输到远程端。这样你就不需要正确引用的情况 - 它会自然地工作:

echo "Deploy project on server ${SERVER_URL}"
work() {
    if [ ! -d /flask-ci-cd ]; then
         # Note: git_token is expanded on host side
         git clone https://sbhusal123:"${git_token}"@gitlab.com/sbhusal123/flask-ci-cd.git /flask-ci-cd
    fi
    cd /flask-ci-cd
    git pull
{
ssh -o StrictHostKeyChecking=no "${SERVER_URL}" bash <<EOF
$(declare -p git_token)  # transfer variables you need
$(declare -f work)       # transfer function you need
work                     # call the function.
EOF
Run Code Online (Sandbox Code Playgroud)