GitLab CI使用WKHTML读取URL文本文件生成PDF报错exit code 1
问题根因排查
1. 全局前置脚本执行失败(核心原因)
你配置了全局before_script,所有Job都会默认执行这两句安装Ruby依赖的命令:
- gem install bundler - bundle install
但convert-pdfJob使用的michaelperrin/wkhtmltopdf镜像根本没有预装Ruby环境,这两句命令执行直接报错退出,触发exit code 1。
2. 目录路径错误
你两处提到的URL存储目录不一致:前期片段写的是pdf-generation/myurls.txt,完整CI配置里写的是generation-pdf/myurls.txt,路径写错会导致xargs找不到目标文件直接报错。
3. 输出目录未提前创建
wkhtmltopdf不会自动创建不存在的父目录,你直接输出到${CI_PROJECT_DIR}/output/,如果这个目录不存在会直接写失败。
4. 命令参数顺序、xargs写法错误
wkhtmltopdf的语法是wkhtmltopdf [全局参数] 输入源1 输入源2... 输出路径,你把输出路径放到了参数中间,逻辑错误;同时xargs配合sh -c的写法缺少$0占位符,会导致第一个URL被吃掉无法正常传入。
5. 执行阶段逻辑错误
你把convert-pdf放在build阶段,pages部署Job放在后面的test阶段,转换PDF的时候Pages还没部署完成,你读取的线上URL要么是旧版本,要么首次运行时根本不存在。
修正后的配置
首先给convert-pdfJob单独覆盖before_script为空,跳过Ruby依赖安装步骤,修正路径、创建目录、调整命令顺序:
image: ruby:2.7 stages: - build - test workflow: rules: - if: "$CI_COMMIT_BRANCH" cache: paths: - vendor/ before_script: - gem install bundler - bundle install pages: stage: test script: - bundle exec jekyll build -d public artifacts: paths: - public rules: - if: '$CI_COMMIT_BRANCH == "gh-pages"' convert-pdf: stage: build image: michaelperrin/wkhtmltopdf:latest # 覆盖全局before_script,避免执行Ruby相关命令 before_script: [] script: # 这里改成你实际存放myurls.txt的目录,确认是pdf-generation还是generation-pdf - TARGET_DIR=${CI_PROJECT_DIR}/pdf-generation - OUTPUT_DIR=${CI_PROJECT_DIR}/output # 提前创建输出目录 - mkdir -p ${OUTPUT_DIR} # 修正xargs写法和参数顺序 - xargs -a ${TARGET_DIR}/myurls.txt sh -c 'wkhtmltopdf --javascript-delay 30000 --dpi 300 -s A4 --disable-smart-shrinking --zoom 1.0 "$@" ${OUTPUT_DIR}/result.pdf' _ artifacts: paths: - ${CI_PROJECT_DIR}/output/* expire_in: 1 week test: stage: test script: - bundle exec jekyll build -d test artifacts: paths: - test rules: - if: '$CI_COMMIT_BRANCH != "gh-pages"' test_variable: stage: test script: - echo "$CI_PROJECT_DIR"
如果需要转换最新部署的Pages内容,可以把convert-pdf调整到test阶段之后,新增一个deploy阶段,确保Pages部署完成后再执行转换。
内容的提问来源于stack exchange,提问作者Badiou30120

