GitHub Actions SSH下载私有仓库文件异常:文件损坏求助
GitHub Actions通过SSH下载私有仓库文件异常的解决方法
问题背景
配置GitHub Actions工作流,目标是通过SSH登录远程服务器,从私有GitHub仓库下载docker-compose文件。为处理run段多行字符串中curl请求头的引号问题,将curl命令拆分为环境变量,但出现文件损坏的问题。
工作流代码如下:
download-file: name: download file runs-on: ubuntu-latest steps: - name: install ssh keys run: | install -m 600 -D /dev/null ~/.ssh/id_rsa echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa host='${{ secrets.SSH_HOST }}' hosts="$(dig +short "$host" | grep -v '\.$' | sed -z 's|\n|,|g')$host" ssh-keyscan -H "$hosts" > ~/.ssh/known_hosts - name: download docker compose file from private repo to server run: ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} # the first curl call to the public repo works. # the file can be opened. the second curl call also # finishes but the file can NOT be opened. "ls -la && cd test && ls -la && curl $CURL_PUBLIC_URL -o $CURL_PUBLIC_O && curl -v -H $CURL_H1 -H $CURL_H2 -H $CURL_H3 -o $CURL_O $CURL_URL && exit" env: CURL_H1: '"\"Authorization: Bearer ${{secrets.PULL_ACCESS_TOKEN}}\""' CURL_H2: '"\"Accept: application/vnd.github.v3.raw\""' CURL_H3: '"\"Content-Type: text/html; charset=UTF-8\""' CURL_O: "docker-compose.yml" CURL_URL: "https://raw.githubusercontent.com/<username>/<repository name>/refs/heads/main/docker-compose.prod.yml" CURL_PUBLIC_URL: "https://raw.githubusercontent.com/thnk2wn/rasp-cat-siren/master/siren/Dockerfile" CURL_PUBLIC_O: "Dockerfile" - name: cleanup run: rm -rf ~/.ssh
问题现象
- 手动登录服务器执行curl命令,文件可正常下载并打开;
- GitHub工作流中执行后,下载的docker-compose.yml文件无法打开,执行
cat docker-compose.yml提示**"found an invalid character in header name"**; - 公开仓库文件下载无异常,私有仓库文件下载后损坏。
补充信息
- 用wget替代curl时,工作流返回400错误,手动执行正常;
- 公开仓库文件下载无异常。
解决方案
问题核心是环境变量的转义格式错误,导致curl请求头被解析为带多余引号的无效格式,修正步骤如下:
1. 修正环境变量的引号转义
无需在环境变量中添加多层转义引号,直接使用正常字符串格式:
env: CURL_H1: "Authorization: Bearer ${{ secrets.PULL_ACCESS_TOKEN }}" CURL_H2: "Accept: application/vnd.github.v3.raw" CURL_H3: "Content-Type: text/html; charset=UTF-8" CURL_O: "docker-compose.yml" CURL_URL: "https://raw.githubusercontent.com/<username>/<repository name>/refs/heads/main/docker-compose.prod.yml" CURL_PUBLIC_URL: "https://raw.githubusercontent.com/thnk2wn/rasp-cat-siren/master/siren/Dockerfile" CURL_PUBLIC_O: "Dockerfile"
2. 修正SSH执行的curl命令格式
在SSH的run命令中,给每个-H参数的变量包裹单引号,避免shell解析时拆分请求头:
run: ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "ls -la && cd test && ls -la && curl $CURL_PUBLIC_URL -o $CURL_PUBLIC_O && curl -v -H '$CURL_H1' -H '$CURL_H2' -H '$CURL_H3' -o $CURL_O $CURL_URL"
3. 简化SSH命令写法(可选)
使用<< 'EOF'定义多行命令字符串,避免YAML多行字符串的转义问题,直接将命令传递到远程服务器执行:
run: | ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'EOF' ls -la cd test ls -la curl $CURL_PUBLIC_URL -o $CURL_PUBLIC_O curl -v -H '$CURL_H1' -H '$CURL_H2' -H '$CURL_H3' -o $CURL_O $CURL_URL EOF
该写法可避免本地shell解析变量,同时环境变量仍会被GitHub Actions正常注入。
验证说明
修正后,curl的请求头会被正确解析为合法格式,私有仓库的docker-compose.yml文件可正常下载并打开,不会出现字符错误。
内容的提问来源于stack exchange,提问作者Lucien Chardon
相关产品推荐
相关产品推荐

