Commit Graph
1602 Commits
Author SHA1 Message Date
yeasy 1e56295251 fix(ci): close two silent false negatives in Identity Guard
An audit found the guard could miss commits it exists to catch.

1. SIGPIPE. Three inner checks used `printf ... | grep -q` under
   `set -euo pipefail`. When grep -q matches early it exits, printf dies of
   SIGPIPE, pipefail turns the pipeline non-zero, the `if` goes false, and the
   offending commit is silently not reported — the guard then prints its
   success line. This file already documents the hazard in a comment and had
   fixed it for the two outer pre-filters; the three inner ones were left as
   pipes. Now here-strings, like the rest.

   Demonstrated on a synthetic revert-style commit (an AI trailer quoted near
   the top, then a 200KB body): the pipe form MISSES it, the here-string form
   detects it. A trailer in the conventional last position happens to survive
   the pipe form, because grep must read to the end before matching — which is
   why this never showed up in practice.

2. `chatgpt` was in BAD_NAME and BAD_ANY but not BAD_TRAILER, so a
   Co-authored-by naming ChatGPT with an email outside anthropic.com/openai.com
   was not caught. Confirmed by test, then added.

Verified before pushing this time: the amended script flags an AI-authored
commit, a large-body early trailer, and a ChatGPT trailer, and scans
claude_guide's full 345-commit history with zero false positives — that repo
has 46 commits with Claude or Anthropic in the subject, none of which are
identity or trailer hits.
2026-07-23 13:13:39 -07:00
yeasy 52f6c73478 ci: bound every workflow job with timeout-minutes
A wedged Chrome/mdPress step held a harness runner for 27 minutes yesterday
(normal run: ~4 min) and ignored `gh run cancel`; it only stopped because that
job happened to carry timeout-minutes: 30. An audit found 66 of the 101 jobs
across the cluster had no timeout at all — the same hang there would have held
a runner for GitHub's 6-hour default.

Values come from measured run history, not guesses. Across ~120 successful
runs the slowest workflow tops out at 10 min (Update Preview Publications),
CI at 6.5, Update Preview PDF at 4.8:

  30 min — jobs that run Chrome/mdPress/pandoc (3x the observed max, and the
           value harness already used)
  15 min — release, publish, deploy, check-link, chaincode-tests
  10 min — dependabot auto-merge

Every value has at least 6x headroom over its job's observed maximum, so this
should never turn a slow-but-working run into a failure.

Verified: all 72 workflow files still parse, and all 101 jobs now carry an
integer timeout in range.
2026-07-23 08:26:48 -07:00
yeasy 7c96d19fd4 fix(links): busybox 官方仓库 pointed at the homepage, duplicating the line above
git.busybox.net is gone — every path under it 404s, including /busybox/ — so
the earlier sweep replaced the dead repo link with https://busybox.net/. That
is byte-identical to the 官网 bullet directly above it, leaving two bullets
with different labels and the same URL, and a 官方仓库 label describing a page
that is not a repository.

Points it at the official source-download index instead and relabels it
源码下载. Verified 200.
2026-07-23 07:40:41 -07:00
yeasy d705dfb631 fix(ci): make the Mermaid fail-closed guard actually fire
The guard added earlier could never trigger. tools/render_mermaid.py has no
nonzero exit path — its own docstring said "Exits 0 even if some/all fail
(non-fatal)" — so `if ! render_mermaid.py ...; then exit 1; fi` never ran its
body, and a build that rendered zero diagrams still passed. Reproduced by
running the script with no Chrome on PATH: it printed the fallback warning and
exited 0.

Adds a --strict flag that exits 1 when Chrome is missing or any diagram fails
to render, and passes it from every workflow invocation. The default stays
lenient so local mobile-reader builds keep working, which is what the exit-0
behaviour was actually for.

Verified both directions: with no Chrome, --strict exits 1 and the default
exits 0; against the real book with Chrome, --strict renders every diagram and
exits 0.
2026-07-23 07:40:28 -07:00
yeasy 1c8f0dc14d chore: remove the remaining VuePress artifacts
Follows the devDependency removal. The build has been mdPress-only since
1.7.0 and nothing referenced these:

- .vuepress/ (config.js + .gitignore). The mirror it configured is still
  live, but no workflow in this repo builds or deploys it, so this was a
  recipe nobody ran. Local .vuepress/dist/ (400 files of Feb-2026 build
  output, never tracked) was removed from the working tree too — with its
  .gitignore gone it would otherwise have shown up as untracked noise.
- docker-compose.yml: the vuepress-offline service, plus the now-unused
  &mdpress-offline anchor that existed only to feed it.
- README: the 'docker run ... :vuepress' one-liner. That tag was last
  pushed 2022-06-25, so readers following it got a four-year-old snapshot
  of the book. 'mdpress serve' immediately above it still works.
- CODEOWNERS, .zhlintignore and check_project_rules.py entries for the
  deleted directory, and the check-link allowlist entry for the mirror
  (no content links to it).

The CHANGELOG entry recording the original CI removal is left alone — it
is history.

Verified: npm test passes (3 + 35), check_project_rules passes 202 files,
docker-compose.yml still parses with no dangling YAML aliases.
2026-07-22 22:51:34 -07:00
yeasy 2c8acc6c9c build(deps): retire the unused VuePress toolchain
The build moved to mdPress in 1.7.0 ('移除遗留的 vuepress 构建,统一使用
mdpress'), but the VuePress devDependencies stayed. Nothing references them:
build/serve/start/pdf all call mdpress, and the only occurrence of vuepress
in code is '.vuepress' inside check_project_rules.py's ignore list. Pages
still ran 'npm ci', so every deploy installed the whole VuePress tree as
dead weight.

They were also the entire source of the repo's 91 Dependabot alerts. The
lockfile carried two copies of several packages; the vulnerable ones were
all VuePress's (dompurify 2.4.3, highlight.js 9.18.5, katex 0.15.6,
mermaid 9.4.3) while mermaid-cli's copies are above every patched
threshold. Removing the three devDependencies drops 16 of the 20 flagged
packages from the tree entirely and leaves the other four at safe versions.

.vuepress/config.js is deliberately kept — the mirror site it configures is
still live, and whether to archive it is a separate decision.

Verified: npm test passes (3 + 35 tests) and check_project_rules passes
202 files.
2026-07-22 20:11:38 -07:00
yeasy a1f63a565b fix(links): repair dead external links found by a cluster-wide sweep
对 13 本书的 1,842 个外链做了一次全量 curl 健康检查(跟随重定向、带浏览器 UA),
逐条排除误报后确认的真死链。替换目标全部逐个验证返回 200。

注意两类**不是**缺陷、因此没有动的:
- platform.claude.com / docs.anthropic.com 当时返回 500,串行重试仍 500,
  但同日早些时候可正常访问——是上游临时故障,不是死链。
- docker_practice 列出的国内 registry 镜像连不上,是因为书里已明确标注
  「已停止服务」「已于 2024 年关闭」,属于故意保留的历史记录。
2026-07-22 16:51:15 -07:00
yeasy a42f94faad ci: add timeout-minutes to Identity Guard
harness_engineering_guide 的 lab/tests/unit/test_project_configuration.py 要求
每个工作流都写 timeout-minutes,我漏了,导致该仓库 CI 变红。

漏检原因值得记一笔:我本地批量跑测试时用的是 `ls tests/test_*.py`,
而 harness 的测试在 lab/tests/ 下、且用 pytest,这个 glob 一个都没匹配到,
于是它被静默报成"OK"。应当按各仓库 ci.yaml 里真正的测试命令来跑。

timeout-minutes 本身也是好实践:避免作业异常时空转到默认上限。
统一给 14 个仓库都加上,与该测试的其余约束(SHA 固定、禁 continue-on-error、
checkout 不持久化凭据)保持一致。
2026-07-22 16:04:50 -07:00
yeasy 38c89065b6 ci: fix Identity Guard trigger — it was never actually running
上一版给 push 只写了 tags-ignore: ['**'],本意是让发布 tag 不再触发一次
重复的全量审计。但 GitHub 的过滤规则是"只给了 tag 过滤器,就只在 tag 上跑",
因此这条配置的真实含义变成"只跑 tag,但忽略所有 tag" —— 工作流一次都不会触发。

症状很有迷惑性:工作流在 API 里状态是 active、名字也正常显示,
只是 runs 数恒为 0,同一次推送里 CI 和 Preview 都正常跑。
改为 branches: ['**'],覆盖全部分支且天然排除 tag,达到原本的意图。

教训记一句:光看"工作流已注册/active"不能算验证,必须确认它真的产生了 run。
2026-07-22 15:37:50 -07:00
yeasy 3781d9c382 ci: fix a latent false negative and cut Identity Guard runtime 50s to 1s
两处都是本地实测发现的,不是推测。

1) 漏判(正确性):尾注预筛写成 `git log --format=%B "$RANGE" | grep -qiE`,
   在 `set -o pipefail` 下 grep -q 命中即退出,左侧 git log 收到 SIGPIPE,
   整条管道返回非 0,if 判定为"没命中"从而跳过整个尾注检查。
   实测:沙箱里 8 条应报错误只报出 6 条,两个带 AI 尾注的提交被静默放过。
   改为 here-string(不再有管道),身份预筛同样改掉以杜绝这一类问题。

2) 性能:全量审计路径(新建分支推送、workflow_dispatch)原先为每个提交
   各起一个 git 子进程,docker_practice 1,592 个提交实测 50 秒。
   现在先用一次 git log 流式预筛,只有命中时才逐个提交定位;
   同一仓库实测降到 1 秒,且不改变任何判定结果。

回归验证:被删分支的真实 4 个提交在 push / pull_request / 新建分支三种
形态下仍全部拦下;专门构造的 2,502 提交仓库(身份流 258KB,远超管道缓冲区)
中埋在末尾的 AI 提交能被检出;14 个仓库完整历史仍然零误报;
范围解析失败仍 fail closed,删除分支仍正确放行。
2026-07-22 15:34:52 -07:00
yeasy f82e13017d ci: add Identity Guard rejecting AI-assistant commit attribution
起因:blockchain_guide 上曾有一个 claude/novel-content-extraction-r0wys3
分支,4 个提交的 author 和 committer 都是 Claude <noreply@anthropic.com>
(内容还是与本书无关的小说抓取脚本)。分支已删除,但暴露出一个缺口:
既有的 .git/hooks/commit-msg 只查提交信息里的 Co-authored-by 尾注,
查不到身份字段;而且本地钩子不随仓库分发,那 4 个提交来自云端会话,
根本不经过本地钩子。

因此把闸门放到服务端:本工作流在 push 与 pull_request 上扫描本次新增
提交的 author/committer 身份与 Co-authored-by 尾注,命中即失败。
本地另配 pre-commit(拦当前身份)与 pre-push(拦 cherry-pick/rebase
带进来的外来提交)作为纵深防御,二者不入库。

判定刻意收窄,避免误伤本仓库群里大量讨论 Claude/Codex 的正文:
只检查身份字段与行首锚定的 Co-authored-by 尾注,绝不扫描自由文本;
姓名要求全等("Claude Dubois" 这样的真人不受影响),邮箱按厂商域名
(含子域)匹配,并覆盖 claude[bot] 这类 GitHub App 身份。

已验证:
- 用被删分支的真实 4 个提交做回归,push / pull_request / 新建分支
  三种到达形态全部拦下;
- 全部 14 个仓库的完整历史(5,715 个提交,含 docker_practice 1,591
  个多人历史与 claude_guide 339 个满是 Claude 的提交)零误报;
- dependabot 的 Co-authored-by、真人 Claude Dubois、正文提到
  co-authored-by 但非尾注的提交,均正确放行;
- 范围解析不出来时 fail closed,只有确实没有 head 提交(删分支)才放行;
- tags-ignore 避免发布 tag 触发一次重复的全量审计。
2026-07-22 15:24:38 -07:00
github-actions[bot]andGitHub 69bf233381 Merge pull request #572 from yeasy/dependabot/github_actions/dependencies-7a5a078ad4
chore(deps): bump actions/checkout from 7.0.0 to 7.0.1 in the dependencies group
2026-07-22 18:44:15 +00:00
dependabot[bot]andGitHub fe46145e4a chore(deps): bump actions/checkout in the dependencies group
Bumps the dependencies group with 1 update: [actions/checkout](https://github.com/actions/checkout).


Updates `actions/checkout` from 7.0.0 to 7.0.1
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0...3d3c42e5aac5ba805825da76410c181273ba90b1)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-22 18:44:00 +00:00
yeasy 51698c89c5 fix(content): correct verified internal inconsistencies across 7 sections
均为书内自证的矛盾,无需外部来源:

- 19.3: golang:1.26-alpine 标注为 ~1GB,但 21.7 将 ~900MB 归给非 alpine 的
  golang:1.26,且 7.17 实测 alpine 版镜像为 295MB——alpine 变体不可能大于其
  非 alpine 版本。改为与 21.7 一致的「golang:1.26 基础镜像的 ~900MB」。
- 20_cases_os: 正文称通用镜像 100-300 MB,紧邻的表格却列 Ubuntu ~80 MB
  (与 4.2 的 ubuntu 24.04 78MB 一致)。正文改为 80-300 MB。
- 4.2: 「查找大于 500MB 的镜像」的 ^[0-9]+GB 不匹配小数,会漏掉 docker 实际
  输出的全部 x.yGB(本书自己的示例即为 2.5GB)。补充可选小数部分。
- 6.2: docker image ls 示例输出把 tag 混入 REPOSITORY 列
  (127.0.0.1:5000/ubuntu:latest + TAG latest),与同块 ubuntu/latest 行及
  本节自述的 tag 格式不符。
- 5.3: 生命周期状态图缺 Stopped --> Running,而 5.3.6 正是讲 docker start
  启动已停止的容器;原图中停止的容器只能被删除。
- 9.5: 端口映射图节点标签 "容器 (Class B: 80)" 语义错乱(Class B 是 IP 地址
  分类,与端口无关),改为「容器 (端口: 80)」。
- appendix/faq/errors.md: 标题「常见错误速查表」与 SUMMARY.md 及 faq/README
  两处链接文字「常见错误处理」不一致(全书 196 篇中唯一一处标题漂移)。
2026-07-16 23:20:25 -07:00
yeasy 7340cc16a8 fix(security): avoid world-writable storage in Laravel multi-stage examples
两处 Laravel 多阶段构建示例把 storage 目录设为 chmod -R 777,且全文没有任何
警告或说明,读者复制粘贴即得到 session/cache/log 目录全局可写的生产镜像。
这与本书 7.11(USER)与第 18 章的最小权限指引相矛盾。

改为将 storage 归属 www-data(php:8.3-fpm-alpine 中 php-fpm worker 的运行用户)
并设为 775:构建期 artisan 以 root 运行不受影响,运行期 www-data 仍可写。
2026-07-16 23:20:25 -07:00
288212bbe9 chore(deps): bump @mermaid-js/mermaid-cli in the dependencies group (#570)
Bumps the dependencies group with 1 update: [@mermaid-js/mermaid-cli](https://github.com/mermaid-js/mermaid-cli).


Updates `@mermaid-js/mermaid-cli` from 10.9.1 to 11.16.0
- [Release notes](https://github.com/mermaid-js/mermaid-cli/releases)
- [Commits](https://github.com/mermaid-js/mermaid-cli/compare/10.9.1...11.16.0)

---
updated-dependencies:
- dependency-name: "@mermaid-js/mermaid-cli"
  dependency-version: 11.16.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-16 18:49:49 -07:00
github-actions[bot]andGitHub 6ad32cc5a8 Merge pull request #569 from yeasy/dependabot/github_actions/dependencies-00a0d7aaea
chore(deps): bump softprops/action-gh-release from 3.0.1 to 3.0.2 in the dependencies group
2026-07-15 18:43:57 +00:00
dependabot[bot]andGitHub 937ad3f1c3 chore(deps): bump softprops/action-gh-release in the dependencies group
Bumps the dependencies group with 1 update: [softprops/action-gh-release](https://github.com/softprops/action-gh-release).


Updates `softprops/action-gh-release` from 3.0.1 to 3.0.2
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/718ea10b132b3b2eba29c1007bb80653f286566b...3d0d9888cb7fd7b750713d6e236d1fcb99157228)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: 3.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-15 18:43:44 +00:00
yeasy 2ef6d80d4f fix(ci): make publication checks runner-safe 2026-07-11 06:44:12 -07:00
yeasy 44822cea16 test(ci): enforce preview publish step order 2026-07-10 19:29:30 -07:00
yeasy 1f970681ee test(ci): enforce exact preview tag commands 2026-07-10 19:29:30 -07:00
yeasy 397c66673b fix(ci): fail closed on preview lookup errors 2026-07-10 19:29:30 -07:00
yeasy 8cd6094ae9 fix(ci): keep preview tag current 2026-07-10 19:29:30 -07:00
yeasy ee0fbd7d38 fix(ci): attest releases and validate offline examples 2026-07-10 19:29:30 -07:00
yeasy daa6661b2b fix(ci): harden publishing and validate examples 2026-07-10 19:29:30 -07:00
yeasy 8eabe30dc2 fix(content): correct verified technical facts across cgroups, namespaces, etcd and k8s sections
- 12.3: daemon.json has no top-level cgroup-driver key; use exec-opts
  native.cgroupdriver (values cgroupfs/systemd) per official dockerd reference
- 12.2: USER namespace is not enabled by default; requires userns-remap
  (aligns with 18.1)
- 14.1: cgroup v1 deprecation and kubelet default-fail happen in v1.35, not
  v1.36 (per kubernetes.io cgroups doc)
- 15_etcd: maintenance window updated after etcd v3.7.0 release (2026-07-08)
  to 3.6/3.7
- 3.9.6: fix dangling sentence order in registry migration note
- tools: add 'from __future__ import annotations' so PEP 604 annotations run
  on Python 3.9 (fixes npm test)
2026-07-10 06:13:27 -07:00
yeasy bd944a2383 fix(ci): embed local images for PDF builds 2026-07-05 19:30:30 +08:00
Baohua YangandGitHub 47a6f56049 Merge pull request #567 from yeasy/dependabot/github_actions/dependencies-0ceda8b77f
chore(deps): bump the dependencies group across 1 directory with 2 updates
2026-07-05 04:22:43 -07:00
dependabot[bot]andGitHub 9058882b73 chore(deps): bump the dependencies group across 1 directory with 2 updates
Bumps the dependencies group with 2 updates in the / directory: [actions/checkout](https://github.com/actions/checkout) and [softprops/action-gh-release](https://github.com/softprops/action-gh-release).


Updates `actions/checkout` from 6 to 7
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

Updates `softprops/action-gh-release` from 2 to 3
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: dependencies
- dependency-name: softprops/action-gh-release
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-30 12:18:26 +00:00
yeasy 68fec82301 ci: sanitize auto-release artifact tag names v1.11.0 2026-06-24 15:39:30 +08:00
yeasy a601794cd4 ci: guard manual auto-release tag name 2026-06-21 15:53:28 +08:00
yeasy 2bcc83dcf4 ci: build and attach HTML reader to each release
Renders Mermaid to SVG via the workflow's Chrome, pandoc --mathml, assembles a
single self-contained responsive HTML reader, and attaches <repo>-<tag>.html to
the GitHub Release next to the PDF. Non-blocking (continue-on-error).
2026-06-21 10:14:47 +08:00
yeasy 9fdffa9d91 fix(content): harden Docker practice guide 2026-06-16 21:23:21 -07:00
yeasy f4e684afeb docs: update Fedora install support list 2026-06-16 19:32:29 -07:00
yeasy 01a6b2dccd fix(content): align compose demo Dockerfiles to COPY over ADD
The app and django compose demos used ADD for plain local files, but the
book's in-text versions of the same examples (11.3_usage.md, 11.6_django.md)
and its own guidance (7.2/7.3, appendix best_practices) all use COPY. Align
the demos with the documented practice.
2026-06-11 23:17:58 -07:00
yeasy 0cfd55af7b fix(content): repair Django tutorial crash and complete the hardening sweep
Follow-ups to the 9 secret-hardening commits (each verified against
docs.docker.com / vendor docs; one outright new bug found and fixed):

- 11.6: eb5e4397 changed settings.py to a hard os.environ lookup but the
  web service never receives POSTGRES_PASSWORD (only db does; DATABASE_URL
  is set but never read) -> step-6 'docker compose up' crashed with
  KeyError. Pass the var to web; harden the leftover literal password in
  the 配置详解 snippet that contradicted the new guidance two lines down;
  blank line after the inserted sentence (bold heading merged into the
  paragraph); dev/prod table no longer claims dev uses 明文 passwords
- 11.8: FAQ still told readers to check passwords in .env after the same
  file banned passwords in .env -> point at secrets/db_password.txt;
  backup sidecar env vars updated to tiredofit/db-backup 4.x interface
  (DB01_* + DB01_PASS_FILE + DB01_BACKUP_INTERVAL - the unprefixed DB_*
  names are ignored by current :latest; verified against upstream README)
- demo/wordpress: compose now references secrets files that ship nowhere
  -> add README with the creation commands from 11.8; demo/django: align
  with the hardened 11.6 (env-injected password, passed to web too)
- 04_image multistage demos: go build without go.mod fails on module-mode
  Go (reproduced by reviewer on go1.26) -> add 'go mod init helloworld'
  matching the 7.17 doc pattern in all three Dockerfiles
- 21.7: init script reworked init-db.sql -> init-db.sh per the official
  image's env-reading .sh hook - removes the baked 'secure_password' AND
  the CREATE DATABASE myappdb collision with POSTGRES_DB that aborted
  first-boot init (ON_ERROR_STOP); compose passes APP_DB_PASSWORD;
  microservices init.sql mount annotated schema-only (POSTGRES_USER:
  appuser would collide with CREATE USER); Dockerfile-redis healthcheck
  now authenticates via REDISCLI_AUTH read from redis.conf (plain
  redis-cli ping gets NOAUTH against requirepass - same class as the
  compose sibling eb5e4397 already fixed); dev-container dev/dev creds
  annotated local-only
- 19.3: Grafana admin password 'admin' sat directly under the newly added
  security warning -> env-injected like the rest of the stack
2026-06-10 12:06:57 -07:00
yeasy eb5e4397e8 docs: remove hardcoded compose secrets 2026-06-08 16:16:36 -07:00
yeasy 070d4d6d69 fix(content): harden secret handling examples 2026-06-06 00:43:52 -07:00
yeasy 67d5fc775a fix(content): harden Compose credential examples 2026-06-04 01:02:59 -07:00
yeasy 130d03bf65 fix(content): harden dashboard and etcd examples 2026-06-03 00:40:40 -07:00
yeasy 8dd6a556c8 fix(content): refresh DCT and monitoring safety guidance 2026-06-02 00:48:00 -07:00
yeasy 3c1720ccc9 应用专业编辑审查(复核续):修复确定性引用/链接/口径等 1 处 2026-06-01 21:04:00 -07:00
yeasy 6fc032f7d6 应用专业编辑审查:修复版本/引用/技术准确性等 3 处 2026-06-01 11:11:28 -07:00
yeasy 1cdd3c582a fix(content): harden Docker examples 2026-06-01 10:33:50 -07:00
yeasy 094965e039 修复编辑问题:错别字/语病/术语/标点等 25 处(自动审校) 2026-05-31 22:20:50 -07:00
yeasy 48e86b7bec fix(appendix): correct .dockerignore typo in image-slimming FAQ v1.10.0 2026-05-28 11:38:28 -07:00
yeasy 9230b49b6b fix(04): replace deprecated openjdk base image with eclipse-temurin and fix 地 typo 2026-05-28 11:38:28 -07:00
yeasy 2185211041 fix(07): note FROM uses pre-FROM ARG, not ENV, for variable substitution 2026-05-28 11:38:27 -07:00
yeasy f09e800020 fix(content): harden copy-paste safety examples 2026-05-27 18:17:24 -07:00
yeasy 3a9ee19d22 docs(content): refresh Kubernetes helper versions 2026-05-26 00:45:20 -07:00