Redesign: example fixes and CI verification (merge 2 of 2) - #23
Merged
Conversation
The diagnostic run found six defects that break a reader following the
examples. This fixes all of them in Korean and English.
- Quote $(pwd) in every docker -v argument (34 places). An unquoted
command substitution splits on a path containing spaces.
- State the minimum tool versions for CycloneDX 1.7: syft 1.51 emits it,
grype 0.118 reads it. An older syft hard-errors on
-o cyclonedx-json@1.7, so the previous remedy ("pin the specification
version") failed on exactly the setup that needed it.
- Add a troubleshooting note for "sbom format not recognized", which is
what an older grype reports when handed a 1.7 SBOM.
- Replace the OSV connectivity check: curl -I https://api.osv.dev
answers 404 even when the service is healthy. Use a real query whose
success is legible.
- Mark the two blocks that cannot pass validation with validate=skip:
the pull_request_target anti-pattern and the cosign placeholder.
Also widen the progress-infra.md ignore rule to every directory. The
rule was anchored to the repository root, so the copy under website/
was untracked and the pre-commit hook swept it into the staged set.
Verified by running the changed blocks: 87 bash blocks pass bash -n and
shellcheck with zero SC2046, verify.sh 13/13, the site builds, and the
OSV replacement command returns a vulns array.
Signed-off-by: Haksung Jang <haksung@sk.com>
The diagnostic run found a workflow that did not parse as YAML and an action tag that never existed. Both were published and neither was caught by review, so check them on every pull request. Two scripts: - check-code-blocks.py (L1, L2) parses yaml/json/xml/toml, runs actionlint on GitHub Actions blocks, checks GitLab CI structure, and runs bash -n plus shellcheck. It carries a --selftest that plants known-bad blocks and asserts they are caught, because a checker that silently inspects nothing also reports zero findings. - check-code-refs.py (L3) resolves every uses: tag and install URL with git ls-remote and curl. actionlint does not resolve references, which is how trivy-action@0.36.0 passed every check while being wrong. Wiring: Layer 4 and Layer 5 run in pre-merge static-verify, with actionlint pinned. Layer 5 only inspects files the pull request touched, since a reference can break without anyone editing the docs. The full sweep runs weekly in example-refs.yml and opens an issue instead of blocking a merge. website/reference/samples/ is excluded because it is generated from output-sample/; fixing the generated copy would be undone on the next regeneration. Blocks that cannot pass carry validate=skip on the fence. Also quote four shell variables in notify-ai-coding-update.yml and sync-agents.yml so actionlint passes across every workflow. Signed-off-by: Haksung Jang <haksung@sk.com>
The runner has no PyYAML, so Layer 4 died on import before checking anything. Install it alongside anthropic, and fail early with a readable message instead of a traceback when it is absent. The import was the visible half of a wider problem. actionlint, shellcheck and tomllib were each handled by printing a skip notice and carrying on, so a machine missing any of them would have reported a clean pass over blocks nobody inspected. That is the failure mode the selftest exists to prevent, reproduced inside the checker itself. Skipped checks are now collected and reported as a failure, listing what did not run. --allow-missing-tools opts out locally; CI does not use it. Running under Python 3.9 now correctly fails on the missing tomllib rather than passing over the toml blocks in silence. Verified against the CI configuration: Python 3.11 with PyYAML gives a clean pass over 536 blocks, and Python without PyYAML reproduces the runner failure and now exits 2 with the message rather than a traceback. check-code-refs.py needs only the standard library plus git and curl, both present on the runner. Signed-off-by: Haksung Jang <haksung@sk.com>
The earlier layers only prove a code block parses. They cannot catch a toolchain that stops fitting together, which is how a syft and grype version pair shipped where the SBOM one produced the other refused to read. example-e2e.sh runs the three sample walkthroughs the way the READMEs describe them and checks values rather than exit codes. Java must yield four components and its scan must contain GHSA-jfh8-c2jp-5v3q, python five, nodejs more than zero once installed with vendor/legacy-parser still carrying no license field, and the SBOM syft produces must actually parse in grype. Exit codes are not enough on their own. Docker on macOS mounts a host path outside its sharing list as an empty directory rather than failing, so syft exits 0 and emits a valid SBOM with nothing in it. --selftest feeds an empty directory through the same path and asserts the check rejects it, so a green run means the assertions looked at something. Image tags are pinned. syft v1.51.1 and grype v0.118.0 are the pair that emit and read CycloneDX 1.7; an older grype fails this check by design. The workflow runs weekly and on demand, and on pull requests only when samples/ or docs/05-tools/ change. A grype database download alone exceeded seven minutes in testing, so this does not belong in the gate that every pull request waits on. Signed-off-by: Haksung Jang <haksung@sk.com>
The npm container ran as root, so every file it wrote under the work directory belonged to root and the runner could not remove them. Cleanup emitted 1668 Permission denied lines, which would bury a real error in any later failure. Run that container as the calling user instead, giving npm a writable HOME and cache path inside the container so it still works. Cleanup also falls back to removing the directory from inside a container if anything root-owned survives. Moving the work directory fixed a second problem found while testing this. It was created with mktemp -d, which on macOS lands under /var/folders, outside Docker Desktop's file sharing list. Docker mounts an unshared path as an empty directory rather than failing, so the nodejs walkthrough could never run on a Mac: npm reported a missing package.json and the script reported an install failure that had nothing to do with npm. The work directory now lives under the repository, which is already a shared path, and the run behaves the same on both systems. Verified locally after the change: all seven assertions pass, including the three nodejs ones that had only ever run in CI, with 73 components matching the CI result exactly, and cleanup writes nothing to stderr. Signed-off-by: Haksung Jang <haksung@sk.com>
The dark search modal put white text on #8ab4f8 at 2.11:1, the only AA failure the U-26 audit found. The active row foreground now uses --brand-fill-fg, which is #fff in light and #062330 in dark, so light keeps its 5.37:1 and dark rises to 7.72:1. That matches how the dark primary button already works. Three lower-priority items from the same audit: - Result headings are h2 but the theme forced weight 400, breaking the heading hierarchy on this page alone. They follow the site token again. - Result rows were 135px tall, mostly from body heading padding and breadcrumb padding the results list does not need. Rows are now 71px, so a 1000px viewport shows 14 results instead of 7. - The match highlight was DocSearch's cream with no dark variant. It now mixes the primary token, and contrast improves in both themes (light 8.39 to 13.18, dark 4.90 to 5.62). Also refreshed two TRUSCA statements that no longer matched the portal: the workflow count is twenty-five, not twenty-three, and a hosted demo now exists where the guide said none was provided. Signed-off-by: Haksung Jang <haksung@sk.com>
The troubleshooting heading still said [1/12] in both the Korean and the English section, while the same file states 13 items twice elsewhere. verify.sh has run 13 checks since the ko/en parity check was added. Found while auditing K17 to K20 for English drift. No anchor links to the heading exist, so renaming it breaks nothing. Signed-off-by: Haksung Jang <haksung@sk.com>
0bd5d5a changed only the first heading in each language, leaving ten [n/12] headings behind while claiming the count was corrected. verify.sh prints [n/13] for all thirteen items. The L4 section described example-e2e.sh but not example-e2e.yml, so a reader would take the layer for a manual script with no automation. Added its schedule and triggers, and the reason it is not a PR gate. Signed-off-by: Haksung Jang <haksung@sk.com>
229cbea added a working directory paragraph without noticing the same explanation fifteen lines below, so the L4 section stated it twice and repeated the database size. Kept the lower paragraph, which also covers gitignore and cleanup, and moved the one sentence it lacked into it. Signed-off-by: Haksung Jang <haksung@sk.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Draft. Second and final merge of the site redesign, covering example-code defects and the
CI that keeps them from coming back. Opened early so the new
static-verifysteps getexercised on a real pull request; K19 through K22 will land on this same branch before it
is marked ready.
Landed so far:
sbom format not recognizedtroubleshooting note, quoted 34 unquoted$(pwd)volumepaths, and replaced the OSV example with a request that returns real data.
check-code-blocks.pyparses every documented code block(YAML, JSON, XML, TOML, GitHub Actions via actionlint, GitLab CI, bash via
bash -nandshellcheck);
check-code-refs.pyresolves everyuses:tag against the remote and everyinstall URL over HTTP. Both are wired into
static-verify, plus a weeklyexample-refs.ymlthat files an issue when an external reference disappears.Test plan
check-code-blocks.py --selftest5/5 — deliberately broken blocks are caught,validate=skipis honouredcheck-code-refs.pyfull run: 15 action refs, 5 install URLs, all resolveactionlint .github/workflows/*.ymlexit 0bash .claude/scripts/verify.sh13/13static-verifygreen on this PR