云原生开发工具数据科学【免费下载链接】docker-stacksReady-to-run Docker images containing Jupyter applications项目地址https://gitcode.com/gh_mirrors/do/docker-stacks点击查看免费下载本文基于 docs/contributing/lint.md 展开介绍 docker-stacksJupyter 官方 Docker 镜像构建仓库如何使用pre-commit git 钩子在开发阶段与 CI 集成阶段强制代码风格与静态检查以及如何用Hadolint对每个Dockerfile做镜像构建规范检查。读完后你将掌握如何安装并运行项目的 lint 钩子、--hook-stage manual背后的机制、.pre-commit-config.yaml中 17 个钩子的完整分工以及 Hadolint 全局忽略规则与行内 ignore 注释的正确用法。整体架构开发期 集成期双重强制项目对规则的执行依赖linter检查器并分两个阶段强制执行引自 docs/contributing/lint.md开发阶段development phase开发者本地提交代码时通过 git 钩子在每次git commit时自动对改动文件跑检查集成阶段integration phaseCIGitHub Actions对合并前的代码再跑一遍全套检查。两个阶段统一用 pre-commit。安装 pre-commit 钩子pre-commit 是一个 Python 包。按文档给出的方式最简单的是安装项目的全部开发依赖其中包含锁定版本的 pre-commit# 安装项目全部开发依赖 pip install -r requirements-dev.txt # 也可以只安装 pre-commit版本取自 requirements-dev.txt 的锁定值 pip install $(grep ^pre-commit requirements-dev.txt)当前仓库 requirements-dev.txt 中锁定的是pre-commit4.6.2其余开发依赖包括docker、plumbum、pytest、pytest-rerunfailures、pytest-xdist、requests等——它们服务于测试与镜像构建工具链而 lint 流程本身只需要其中的 pre-commit。随后把项目配置的 git 钩子脚本安装到本地 git 仓库pre-commit installdocs/contributing/dev-setup.md 中给出的安装命令是pre-commit install --install-hooks多出的--install-hooks参数会额外注册 pre-push 等其它阶段的钩子日常开发用pre-commit install注册 pre-commit 阶段即可。安装完成后pre-commit连同配置好的钩子会在每次git commit时自动对每个被修改的文件运行检查。手动全量运行与--hook-stage manual机制除了提交时自动触发也可以随时对全部文件手动跑一遍检查pre-commit run --all-files --hook-stage manual两个要点必须理解Docker 依赖Hadolint 钩子hadolint-docker是通过运行hadolint/hadolint容器镜像来执行检查的因此执行上面这条命令时本地docker守护进程必须处于运行状态为什么带--hook-stage manualpre-commit 默认只对“被修改过的文件”跑钩子而mypy --follow-imports error这类需要全项目一致性的静态类型检查在“只给部分文件”的输入下无法得出正确结果。项目因此把需要全项目视图的钩子划入manual阶段——它们不会随git commit自动跑但会随pre-commit run --hook-stage manual跑。.pre-commit-config.yaml中的原注释解释得很清楚见 .pre-commit-config.yaml# Unfortunately, pre-commit only runs on modified files # This doesnt work well with mypy --follow-imports error # To work around this we run mypy only in manual mode # So it wont run as part of git commit command, # but it will still be run as part of pre-commit workflow and give expected results stages: [manual]CI 侧的等价执行集成阶段由 GitHub Actions 工作流.github/workflows/pre-commit.yml承担其触发条件与执行方式值得注意触发时机pull_request、push到main分支、以及手动workflow_dispatch运行环境ubuntu-24.04运行器Python3.125 分钟超时安装方式与本地开发保持同一版本来源——pip install $(grep ^pre-commit requirements-dev.txt)只装 pre-commit 不装其它开发依赖执行命令与本地完全一致的pre-commit run --all-files --hook-stage manual并配置了concurrency组以取消同 ref 的旧运行、permissions: {}最小权限。这套“同一条命令跑两个阶段”的设计避免了本地与 CI 规则漂移。完整钩子清单.pre-commit-config.yaml逐项解读.pre-commit-config.yaml 是整套 lint 体系的“总清单”顶层用exclude: ^LICENSE.md$把许可证文件排除在所有检查之外。下面按“格式化 → 静态类型 → 通用检查 → Dockerfile → 其它语言/文件”的顺序梳理全部钩子。Python 代码风格与格式化自动改写钩子作用关键参数pyupgrade自动升级语法到目标 Python 版本的写法--py312-plusisort自动排序 import--profile black与 black 兼容的排序风格black自动格式化--target-versionpy312三者组合升级语法 排 import 格式化构成 Python 代码的“零争议”风格基线且全部会自动改写文件。Python 静态类型检查manual 阶段钩子作用关键配置mypy静态类型检查--config ./mypy.inistages: [manual]additional_dependencies预装 14 个类型桩/库basedpyright静态类型检查Pyright 的社区 forkstages: [manual]additional_dependencies预装 11 个依赖两个类型检查器都在manual阶段原因如前所述类型检查要求整个项目视图一致basedpyright 的注释同样写明 “Type checking requires the whole project to be consistent, so we run this hook only in manual mode”。其它文件类型的自动格式化与通用卫生检查prettier.pre-commit-config.yaml统一格式化 YAML、JSON、Markdown 等文件pre-commit-hooks默认六件套.pre-commit-config.yamlcheck-added-large-files防大文件入库、check-executables-have-shebangs可执行文件必须有 shebang、check-shebang-scripts-are-executable带 shebang 的脚本必须可执行、end-of-file-fixer保证文件以换行结尾、requirements-txt-fixer排序并去重 requirements、trailing-whitespace清理行尾空白。Dockerfile 检查Hadolint见下文“Image Lint”专节YAML / Shell 检查yamllint参数[-d {extends: relaxed, rules: {line-length: disable}}, -s]即采用relaxed预设、关闭行宽限制并静默输出与 docs/conf.py 等长行文档配置文件的共存需求相匹配shfmtShell 脚本格式化--write --indent4 --case-indenttrue把改写直接落盘shellcheckShell 脚本静态检查-x表示跟随source引入的文件一起检查——这对images/docker-stacks-foundation下大量.sh钩子脚本的组织方式很重要。Python lint 与 Markdownruff-check--fix自动修复flake8Python lint 的第二道检查markdownlint-cli2Markdown 风格检查--fix自动修复。项目根目录的.markdownlint.yaml采用default: true启用全部规则仅对MD013行宽放宽到 200 字符并关闭表格检查nbstripout提交前剥离 Jupyter Notebook 的输出单元格避免执行结果混入版本库tests/by_image/*/data/下的.ipynb测试夹具即受益于此nbQA.pre-commit-config.yaml把 Python 生态工具“搬进” Notebook 代码单元格执行——nbqa-pyupgrade --py312-plus、nbqa-isort、nbqa-black --target-versionpy312、nbqa-flake8即 Notebook 与.py文件享受同一套风格检查blacken-docs对文档文件中的 Python 代码块跑 black参数--target-versionpy312, --skip-errors其中--skip-errors明确用于容忍文档代码块里 Jupyter 特有的%/!魔术命令写法。pre-commit.ci 自动更新配置文件尾部.pre-commit-config.yaml声明ci: autoupdate_schedule: monthly # Docker hooks do not work in pre-commit.ci # basedpyright environment exceeds the 250MiB per-hook limit of pre-commit.ci # This hook only runs in the manual stage (as part of the pre-commit GitHub workflow) anyway skip: [basedpyright, hadolint-docker]即 pre-commit.ci 每月自动更新钩子版本但跳过basedpyright其虚拟环境超过 pre-commit.ci 单钩子 250MiB 限制且该钩子本就只在 manual 阶段、由 GitHub 工作流运行和hadolint-docker容器类钩子在 pre-commit.ci 沙箱中无法工作。每个钩子的rev旁都带# frozen: 版本号注释是自动更新时的版本锚点。mypy 与 basedpyright 的项目级配置两个 manual 阶段类型检查器的行为分别由 mypy.ini 和 pyrightconfig.json 约束。mypy.ini 的关键项[mypy] python_version 3.12 follow_imports error strict True no_incremental True warn_unreachable True disallow_any_unimported True enable_error_code deprecated, exhaustive-match, ignore-with-out-code, ...完整列表见 mypy.inienable_error_code还包括mutable-override、possibly-undefined、redundant-expr、redundant-self、truthy-bool、truthy-iterable、unimported-reveal、unused-awaitable等。值得留意的两点follow_imports error任何 import 解析失败都会成为错误——这正是它与 pre-commit“只处理修改文件”的行为冲突、必须放 manual 阶段的直接原因配置文件头部注释mypy.ini也写明 “We use mypy as part of pre-commit checks”分节策略对确认静态类型化的包jupyter_core、plumbum、pytest/_pytest、tenacity见 mypy.ini设置follow_imports silent让 mypy 进入这些包拿真实类型而非Any对暂未提供类型信息的包Cython、matplotlib、pandas、pyspark、tensorflow、torch见 mypy.ini设置ignore_missing_imports True以免阻塞检查。这个分节方案与.pre-commit-config.yaml中 mypy 钩子的additional_dependencies预装types-requests、types-tabulate等类型桩是配套的。pyrightconfig.json 的关键项{ typeCheckingMode: standard, pythonVersion: 3.12, executionEnvironments: [ { root: tests/by_image/pyspark-notebook/units, reportMissingImports: false, reportMissingModuleSource: false }, ... ] }即 basedpyright 以standard级别、Python 3.12 语义检查整个项目同时对 5 个测试目录pyspark/pytorch/tensorflow 的units与 scipy 的units、data放宽“缺失导入/模块源”报告——这些目录下的单元测试代码运行在镜像内部依赖如pyspark、torch、tensorflow、pandas本地环境并不安装。完整清单见 pyrightconfig.json。Image Lint用 Hadolint 约束每个 Dockerfile作为 Docker 镜像仓库docker-stacks 的核心产物就是各images/*/Dockerfile与docs/using/recipe_code/*.dockerfile配方文件因此它对 Dockerfile 的检查独立成节引自 docs/contributing/lint.md使用Hadolint分析每个Dockerfile使其符合 Docker 官方最佳实践。钩子如何跑.pre-commit-config.yaml里有两个Hadolint 钩子.pre-commit-config.yaml默认hadolint-docker作用于标准Dockerfile文件重命名为 “Lint *.dockerfile Dockerfiles” 的第二个钩子types: [file]files: \.dockerfile$把仓库里以.dockerfile为后缀的配方文件如 docs/using/recipe_code/pip_install.dockerfile也纳入检查。两者entry都显式使用hadolint/hadolint:v2.15.1 hadolint注释提醒该镜像 tag 必须与rev同步手动升级自动更新不会改它——这也是钩子版本可复现性的一个细节。全局忽略规则.hadolint.yaml仓库根的 .hadolint.yaml 声明了对所有镜像默认忽略的规则--- ignored: - DL3006 - DL3008 - DL3013 - DL3066文档对其中三条的取舍理由见 docs/contributing/lint.mdDL3006FROM 应固定版本 tag项目采用特定的镜像 tag 管理策略——docker-stacks-foundation的FROM子句虽然“固定”但它是基于构建参数ARG的而下游镜像FROM最新版是有意为之构建时依赖最新 foundationDL3008RUN 中 apt-get 应指定版本系统包始终更新到最新版DL3013pip 安装应固定版本始终用pip安装最新版。从配置文件内容看实际忽略列表比文档列举的多出一条DL3066Shebang 应为绝对路径说明文档的说明与配置文件存在轻微不同步以.hadolint.yaml的实际内容为准。行内忽略# hadolint ignore注释对其它需要豁免的规则首选做法是在 Dockerfile 中逐条标记在被豁免的指令正上方写一条特殊注释例如FROM ubuntu # hadolint ignoreDL3003,SC1035 RUN cd /tmp echo hello!这一做法在本仓库中广泛存在可作为真实案例参考docs/using/recipe_code/ijavascript.dockerfile分别对DL3016禁止使用默认分支 tag与DL3059应合并连续 COPY做豁免images/julia-notebook/Dockerfile对DL3059的豁免images/pytorch-notebook/Dockerfile对DL3013的豁免GPU 变体下 torch 版本由 CUDA 镜像决定需安装“最新版”匹配images/docker-stacks-foundation/Dockerfile对SC2016shellcheck 规则的豁免。从这些用例可以看出团队对“全局忽略”与“行内豁免”的边界把握有明确政策依据的规则才进.hadolint.yaml全局忽略个别场景的例外一律在 Dockerfile 里就地声明这样每条豁免都伴随上下文可审计、可追溯。小结把这套流程落到日常开发克隆仓库后pip install -r requirements-dev.txt或直接按 requirements-dev.txt 中的锁定版本安装 pre-commit再pre-commit install注册钩子日常提交依赖 git commit 时自动触发的钩子需要全量体检尤其触发 manual 阶段的 mypy/basedpyright 与需要 Docker 运行的 hadolint时执行pre-commit run --all-files --hook-stage manual并确保 Docker 守护进程在运行修改 Dockerfile 遇到 Hadolint 报错时先看 .hadolint.yaml 的全局策略是否符合项目镜像 tag 政策不符合再用# hadolint ignoreDLxxxx在指令上方就地豁免排查“为什么这个钩子没在 commit 时跑”时先查它是否声明了stages: [manual]如 mypy、basedpyright或是否被 pre-commit.ci 的skip列表跳过。以上所有配置均可在当前仓库直接查证钩子清单与阶段声明见 .pre-commit-config.yamlCI 执行见.github/workflows/pre-commit.yml类型检查配置见 mypy.ini 与 pyrightconfig.jsonDockerfile 检查策略见 .hadolint.yaml 与 docs/contributing/lint.md。赞分享云原生开发工具数据科学【免费下载链接】docker-stacksReady-to-run Docker images containing Jupyter applications项目地址https://gitcode.com/gh_mirrors/do/docker-stacks点击查看免费下载相关推荐Glances 代码库 Lint 与格式化实战指南基于 Ruff 与 Pre-commit 的质量检查工作流Glances 代码库 Lint 与格式化实战指南基于 Ruff 与 Pre commit 的质量检查工作流 本篇技术指南围绕 Glances 开源仓库中面向指标监控监控大盘CLI告警MCP 服务Hadolint 集成实战指南将 Dockerfile Linter 接入代码审查、CI/CD、编辑器与 pre-commitHadolint 集成实战指南将 Dockerfile Linter 接入代码审查、CI/CD、编辑器与 pre commit 本文以 docs/INTEGR开发工具代码质量HIXL 开源贡献实战指南从 Issue 协作、PR 规范到 pre-commit 合规检查的完整流程HIXL 开源贡献实战指南从 Issue 协作、PR 规范到 pre commit 合规检查的完整流程 HIXLHuawei Xfer Library是昇通信网络高性能计算CANNAscend上一篇终极指南Kedro内存数据集高效管理与性能优化技巧下一篇MJML mj-style 组件完全指南向邮件模板注入自定义 CSS 的两种模式与底层实现原理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
