У меня проблема с моим конвейером Azure. Сам конвейер довольно прост, и его цель в примере — запуск gen.py:
# azure-pipelines.yml
trigger:
- master
pool:
vmImage: 'windows-latest'
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.x'
addToPath: true
- script: |
python.exe -m pip install --upgrade pip
python.exe -m pip install setuptools
pip install -r $(Build.Repository.LocalPath)\requirements312.txt
displayName: 'Install dependencies'
- script: |
set PYTHONPATH=$(Build.Repository.LocalPath)\cfg\00-config-tools-ext
set CONFIG_PATH=$(Build.Repository.LocalPath)\cfg\config.yml
python $(Build.Repository.LocalPath)\cfg\gen.py
displayName: 'Run gen.py'
Программа cfg/gen.py использует другие программы (.yml/.py) из того же каталога (cfg), например cfg/00-config-tools-ext/sanity_check.py.
gen.py вызывает sanity_check.py следующим образом:
из sanity_check импортируйте check_sanity_config
if __name__ == '__main__':
check_sanity_config()
В sanity_check.py теперь есть следующая функция, которая хочет открыть cfg/config.yml (отрывок из исходного файла):
import yaml
def check_sanity_config():
with open('config.yml', "r", encoding = "utf-8") as stream:
config_yml = yaml.safe_load(stream)
if __name__ == '__main__':
check_sanity_config()
Когда я запускаю конвейер, как показано выше, я получаю эту ошибку:
PYTHONPATH: D:\a\1\s\cfg\00-config-tools-ext
File "D:\a\1\s\cfg\gen.py", line 53, in <module>
Using config file at: D:\a\1\s\cfg\config.yml
check_sanity_config()
File "D:\a\1\s\cfg\00-config-tools-ext\sanity_check.py", line 132, in check_sanity_config
with open('config.yml', "r", encoding = "utf-8") as stream:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'config.yml'
Единственный обходной путь для меня сейчас — использовать абсолютный путь из Azure следующим образом:
def check_sanity_config():
config_path = 'D:\\a\\1\\s\\cfg\\config.yml'
with open(config_path, "r", encoding = "utf-8") as stream:
config_yml = yaml.safe_load(stream)
Однако меня это решение не устраивает, поскольку оно требует изменения сотен относительных путей по всему проекту, и локальное выполнение становится невозможным. На моей локальной машине с Windows все работает отлично. Кажется, проблема связана с «с открытым [файлом]», почему-то Azure не может его найти. Не могли бы вы предложить лучший способ? Я уже пробовал много разных подходов, используя, например, относительные пути, $(Pipeline.Workspace), которые не работают. Как мне заставить эти относительные пути работать или мне придется переписать все операторы «с открытым [файлом]»?
Спасибо


Ошибка, которую вы видите, заключается в том, что sanity_check.py ищет config.yml в том же каталоге, в котором он находится (cfg/00-config-tools-ext/), но файл config.yml на самом деле находится в каталоге cfg/.
Вы можете указать полный путь к файлу config.yml в своем файле sanity_check.py. Обратитесь к приведенным ниже сценариям.
import os
import yaml
def check_sanity_config():
script_dir = os.path.dirname(os.path.abspath(__file__))
config_path = os.path.abspath(os.path.join(script_dir, '..', 'config.yml'))
with open(config_path, "r", encoding = "utf-8") as stream:
config_yml = yaml.safe_load(stream)
Тестируя ваши скрипты на своем локальном компьютере, я получил ту же ошибку. Не знаю, чем ваша среда отличается от моей.
Спасибо, так что, думаю, мне придется изменить пути, и другого выхода нет. Мне просто интересно, что это работает на моей локальной машине, но не в Azure.