You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitHub Actions中Python脚本获取推送提交文件列表失败求助

问题:GitHub Actions中无法通过Git命令获取推送提交的文件列表

我在推送提交触发GitHub Action时,尝试用Python的subprocess.getoutput()方法获取最后一次提交的推送文件列表。本地运行以下命令完全正常:

git_diff = subprocess.getoutput('git diff-tree --no-commit-id --name-only -r $GITHUB_SHA')

但在GitHub Actions的Ubuntu服务器上执行时返回错误:

git_diff: fatal: ambiguous argument 'zag2b54s': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

已确认环境依赖安装正常,本地测试无问题,但在GitHub Actions中出现提交哈希无法识别的情况,不确定是Git用法问题还是GitHub Actions配置问题。附上相关Workflow配置和Python脚本,求告知在GitHub Actions服务器的Python脚本中,获取最后一次推送提交文件列表的正确Git命令或解决方法。


相关Workflow配置

name: Automation for csv, py and diagrams files of Sequel pushed files

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

permissions: write-all

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Set up Python 3.11
      uses: actions/setup-python@v3
      with:
        python-version: "3.11"
    - name: Install dependencies
      run: |
        sudo apt-get update -y \
            && sudo apt-get upgrade -y \
            && sudo apt-get install graphviz git -y \
            && python -m pip install --upgrade pip \
            && pip install pandas sql-metadata diagrams
    - name: App with Automation for csv and diagrams
      run: |
        # stop the build if there are Python syntax errors or undefined names
        python automation_csv_diagram.py --last_commit

相关Python脚本

import subprocess
import sys
from glob import glob
from re import findall, IGNORECASE, match, MULTILINE, search, S, sub

global REQUEST_DIR
REQUEST_DIR = "bq"


def pickup(lastcommit_fct: bool) -> list[str]:
    """
    :param lastcommit_fct: bool
    获取子目录中的SQL文件列表
    :return: List[str]
    """
    global REQUEST_DIR
    if lastcommit_fct:
        if not os.name == "nt":  # 判断是否为GitHub Actions的Ubuntu环境
            git_diff = subprocess.getoutput('git diff-tree --no-commit-id --name-only -r $GITHUB_SHA')
        else:
            git_diff = subprocess.getoutput('git diff-tree --no-commit-id --name-only -r HEAD')
        files = findall(".*\.sql", git_diff, MULTILINE | IGNORECASE)
##DEBUG MODE###############################
        mode = True
        if mode:
            var_githubsha = subprocess.getoutput("echo $GITHUB_SHA")
            sys.exit('github sha: ' + var_githubsha + "\ngit_diff: " + git_diff + '\nfiles: ' + str(files))
###########################################
        if len(files) > 0:
            files = [y for y in [x.strip() for x in files] if match(r".*\.sql", y, IGNORECASE)]
        else:
            sys.exit("Pas de fichier SQL dans le dernier commit git_diff" + git_diff)

    if not lastcommit_fct:
        files: list = glob(f'{REQUEST_DIR}/**/*.sql')
    return sorted(files)


def main(lastcommit_fct):
    files = pickup(lastcommit_fct)


if __name__ == '__main__':
    option = str(sys.argv[1])
    if option == "--all_directories":
        main(False)  # 生成./bq目录下所有SQL文件的文档
    elif option == "--last_commit":
        main(True)  # 仅生成最后一次提交中SQL文件的文档
    else:
        print("""运行脚本生成./bq目录下所有Sequel文件的文档:
$python automation_csv_diagram --all_directories

运行脚本生成最新推送的Sequel文件的文档:
$python automation_csv_diagram --last_commit""")

解决方案

问题根源

  1. actions/checkout@v3默认仅拉取最新提交:不完整的仓库克隆导致Git无法识别完整提交历史,$GITHUB_SHA对应的提交无法被正确解析。
  2. Shell变量解析失败:Python的subprocess.getoutput()使用单引号包裹命令时,Bash不会解析$GITHUB_SHA变量,导致传递给Git的是字符串$GITHUB_SHA而非实际提交哈希。

修复步骤

1. 修改Workflow的checkout步骤,拉取完整仓库历史

更新actions/checkout配置,添加fetch-depth: 0拉取所有历史:

- uses: actions/checkout@v3
  with:
    fetch-depth: 0  # 拉取完整仓库历史

2. 修复Python脚本中的环境变量传递问题

有两种可靠方式解决:

  • 方式一:改用双引号包裹命令:让Bash自动解析环境变量
git_diff = subprocess.getoutput("git diff-tree --no-commit-id --name-only -r $GITHUB_SHA")
  • 方式二:直接在Python中读取环境变量(推荐,避免Shell解析问题)
import os
# ...
git_sha = os.environ.get('GITHUB_SHA')
git_diff = subprocess.getoutput(f'git diff-tree --no-commit-id --name-only -r {git_sha}')

3. 基于GitHub事件的优化(可选)

如果仅需获取本次推送的修改文件,可直接读取GitHub事件文件,无需调用Git命令:

import json
import os

def get_pushed_files():
    event_path = os.environ.get('GITHUB_EVENT_PATH')
    with open(event_path, 'r') as f:
        event_data = json.load(f)
    # 提取推送事件中所有新增、修改、删除的文件
    files = []
    for commit in event_data.get('commits', []):
        files.extend(commit.get('modified', []))
        files.extend(commit.get('added', []))
        files.extend(commit.get('removed', []))
    # 去重并筛选SQL文件
    sql_files = list(set([f for f in files if f.endswith('.sql')]))
    return sorted(sql_files)

内容的提问来源于stack exchange,提问作者Romain Boyrie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 20:16:05