From 0334f3771d5b995e2587416d749187fa98b6ed70 Mon Sep 17 00:00:00 2001 From: Reese Herber Date: Fri, 31 Jul 2026 16:30:15 -0700 Subject: [PATCH] ci: add OpenWiki generation workflow (org Bedrock key) --- .github/workflows/openwiki-update.yml | 166 ++++++++++++++++++++++++++ .gitignore | 1 + 2 files changed, 167 insertions(+) create mode 100644 .github/workflows/openwiki-update.yml diff --git a/.github/workflows/openwiki-update.yml b/.github/workflows/openwiki-update.yml new file mode 100644 index 0000000000..e464db2dcb --- /dev/null +++ b/.github/workflows/openwiki-update.yml @@ -0,0 +1,166 @@ +# OpenWiki Update workflow +# Runs the OpenWiki documentation agent (langchain-ai/openwiki) on every push to +# `main` (plus a weekly backstop) to keep the agent-navigable `openwiki/` wiki +# current, then opens/refreshes a single rolling PR against `main`. +# +# LLM serving: Bedrock's OpenAI-compatible endpoint with GLM-5 (zai.glm-5) — the +# same serving stack as psd401/aistudio. No third-party LLM vendor; spend lands +# on the district AWS account. Verified in aistudio 2026-07-09 against +# bedrock-runtime.us-west-2.amazonaws.com. Do NOT switch to OPENWIKI_PROVIDER= +# anthropic + Claude on the Bedrock /anthropic path: openwiki's @langchain/ +# anthropic layer unconditionally sends REQUEST-TOP-LEVEL cache_control +# (first-party auto-caching), which Bedrock's compat layer rejects with +# "cache_control: Extra inputs are not permitted" (block-level caching is fine, +# but openwiki exposes no knob). +# +# ⚠️ Scaffolder clobber warning: running `openwiki code --init` locally rewrites +# THIS FILE with openwiki's stock template (OpenRouter provider, unpinned +# install, no secret gate, add-paths spanning CLAUDE.md/AGENTS.md). Never accept +# that rewrite — restore this hardened version. In CI this is harmless: the +# create-pull-request `add-paths: openwiki` cap keeps any scaffold churn out of +# the rolling PR. +# +# Manual prerequisites (one-time, out of code): +# 1. Make `BEDROCK_API_KEY` available to this repository as either a repo +# secret or a selected-repository psd401 organization secret. It must be a +# LONG-TERM Bedrock API key (AWS console -> Bedrock -> API keys -> +# long-term; it is an IAM service-specific credential). Short-term keys +# expire in <=12h and will strand the schedule. +# 2. Enable Settings -> Actions -> General -> Workflow permissions -> +# "Allow GitHub Actions to create and approve pull requests". +# (The initial `openwiki/` tree is committed with this workflow; the +# `--update` runs below refresh it incrementally.) +# +# The scheduled PR is opened by the default GITHUB_TOKEN, so (by GitHub's +# anti-recursion rule) it does NOT trigger other push/PR workflows. That is +# intentional for a docs-only PR and saves review-bot cost. +name: OpenWiki Update + +on: + workflow_dispatch: + push: + branches: [main] + schedule: + # UTC. 08:00 UTC = midnight PST. Weekly (Mon) backstop in case push-driven + # runs were skipped (e.g. the provider secret was temporarily absent). + - cron: "0 8 * * 1" + +# One update at a time. A push landing mid-run queues exactly one follow-up +# (GitHub coalesces pending runs per group), which then covers every commit +# that arrived meanwhile. No cancel-in-progress: killing a mid-flight LLM run +# wastes its spend without saving anything. Self-trigger note: merging the +# rolling openwiki/update PR pushes to main and re-runs this workflow, but +# openwiki's no-op detection (git diff from the recorded gitHead) sees only +# openwiki/ paths changed and skips the LLM pass. +concurrency: + group: openwiki-update + cancel-in-progress: false + +permissions: + contents: write + pull-requests: write + +jobs: + update: + name: Regenerate OpenWiki + runs-on: ubuntu-latest + # Runaway guard: caps Actions minutes + LLM spend if a run hangs. Incremental + # `--update` runs are small; a full first-generation is done locally, not here. + timeout-minutes: 60 + + steps: + # Graceful gate: until the BEDROCK_API_KEY secret is configured, every main + # push would otherwise fail this workflow red. Skip cleanly instead — the + # remaining steps are conditioned on this. + - name: Check provider secret + id: gate + env: + BEDROCK_KEY: ${{ secrets.BEDROCK_API_KEY }} + run: | + if [ -z "$BEDROCK_KEY" ]; then + echo "BEDROCK_API_KEY not configured — skipping OpenWiki update (see workflow header for one-time setup)." + echo "configured=false" >> "$GITHUB_OUTPUT" + else + echo "configured=true" >> "$GITHUB_OUTPUT" + fi + + - name: Check out repository + if: steps.gate.outputs.configured == 'true' + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + # Generate from, and propose against, the same branch. create-pull-request + # builds the PR branch from the checked-out HEAD, so pin `ref` to the PR + # base (`main`): scheduled runs use the default branch and a manual dispatch + # can be launched from any ref, but this PR always targets `main`. Without + # this, a dispatch from another ref would open a PR full of that ref's delta + # rather than just the regenerated wiki. + ref: main + # Full history: openwiki --update reads the previous run's gitHead from + # openwiki/.last-update.json and runs `git diff ..HEAD` for its + # no-op detection and changed-paths summary. With the default depth-1 clone + # that SHA is absent after the first merged update PR, degrading every + # later run's diff to a fatal git error. + fetch-depth: 0 + # Harden: do not leave the GITHUB_TOKEN in .git/config while the OpenWiki + # agent runs arbitrary LLM-driven code with filesystem access. The + # create-pull-request step below authenticates via its own `token` input + # (defaults to github.token), so persisted checkout credentials aren't needed. + persist-credentials: false + + - name: Set up Node.js + if: steps.gate.outputs.configured == 'true' + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: "22" + + - name: Install OpenWiki + if: steps.gate.outputs.configured == 'true' + # Version-pinned: this job runs on a schedule with a provider secret, so we + # do not auto-adopt an unreviewed OpenWiki release. Bump deliberately. + # 0.2.0 emits Open Knowledge Format (OKF v0.1) pages — YAML front matter + # with a required `type` and reserved per-directory index.md. The one-time + # full OKF regeneration of openwiki/ is generated locally alongside this + # pin; these --update runs maintain it incrementally. + # + # Transitive deps stay caret-ranged (global install has no lockfile). We do + # NOT pass --ignore-scripts: OpenWiki depends directly on + # @langchain/langgraph-checkpoint-sqlite -> better-sqlite3, whose install + # script builds a required native binding. Residual supply-chain risk is + # bounded by the job-scoped GITHUB_TOKEN, human-reviewed PR, and + # `add-paths: openwiki` cap. + run: npm install --global openwiki@0.2.0 + + - name: Run OpenWiki + if: steps.gate.outputs.configured == 'true' + # `code` mode is explicit (0.1.0 made the CLI general-purpose). + run: openwiki code --update --print + env: + OPENWIKI_PROVIDER: openai-compatible + OPENWIKI_MODEL_ID: zai.glm-5 + OPENAI_COMPATIBLE_BASE_URL: https://bedrock-runtime.us-west-2.amazonaws.com/openai/v1 + OPENAI_COMPATIBLE_API_KEY: ${{ secrets.BEDROCK_API_KEY }} + # 0.2.0 added anonymous CLI telemetry. District policy: no third-party + # usage phone-home from CI. DO_NOT_TRACK also covers future telemetry libs. + OPENWIKI_TELEMETRY_DISABLED: "1" + DO_NOT_TRACK: "1" + # Optional LangSmith tracing — enable only if a LANGSMITH_API_KEY secret exists: + # LANGSMITH_API_KEY: ${{ secrets.LANGSMITH_API_KEY }} + # LANGCHAIN_PROJECT: openwiki + # LANGCHAIN_TRACING_V2: "true" + + - name: Create OpenWiki update pull request + if: steps.gate.outputs.configured == 'true' + # Third-party action — SHA-pinned. v8+ declares node24, ahead of GitHub's + # 2026 removal of the node20 action runtime from hosted runners. + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 + with: + base: main + add-paths: openwiki + branch: openwiki/update + commit-message: "docs: update OpenWiki" + title: "docs: update OpenWiki" + body: | + Automated OpenWiki documentation update. + Generated by the scheduled OpenWiki workflow (`.github/workflows/openwiki-update.yml`). + + Scoped to `openwiki/` only — the hand-curated `CLAUDE.md` is untouched. diff --git a/.gitignore b/.gitignore index ca13ea587e..b207ba2b9f 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,4 @@ tmp/ .opencode/package-lock.json branding/ deploy/cert.p12 +.openwiki/