Files
dingtalk-workspace-cli/docs/automation.md
T
玉澜andCursor 941bf01e30 Remove unused dws recovery CLI and continue multi-skill content framework.
Drop the recovery package/commands and related Schema/skill teaching so agents
stop being steered at a dead surface, while keeping mono↔multi content QA work.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-05 20:23:37 +08:00

6.7 KiB

Maintainer Automation Notes

This document keeps agent- and maintainer-specific workflow notes out of the repository root while preserving repo-local guidance for automation.

Read Order

  1. README.md
  2. CONTRIBUTING.md
  3. docs/architecture.md
  4. This document

Project Snapshot

  • dws is a Go-based DingTalk Workspace CLI and MCP runtime bridge.
  • Product commands are loaded dynamically via internal/plugin from bundled descriptors.
  • Command handlers live in internal/helpers; runtime execution flows through internal/executor and internal/transport.

Repository Map

  • cmd: public CLI entrypoint
  • internal/app: root command wiring, static utility commands, plugin loading
  • internal/helpers: product command handlers (dev, chat, calendar, contact, etc.)
  • internal/plugin: plugin-based dynamic command loader
  • internal/cli: catalog types and static endpoint loader
  • internal/executor: invocation dispatch and result handling
  • internal/transport: MCP HTTP client and request signing
  • internal/auth: login, token management, agent-code detection
  • internal/audit: user operation audit log
  • internal/errors: structured error model with categories and hints
  • internal/keychain: OS keychain integration for credential storage
  • internal/security: endpoint allowlist and domain trust
  • internal/pat: PAT (Personal Access Token) authorization flow
  • docs/: public architecture and reference docs
  • scripts/: build, test, lint, packaging, and policy checks
  • test/: CLI, integration, contract, unit, and skill E2E test suites

Task Routing

  • Add or fix a command path: start from internal/helpers (handler implementations) or internal/app (command tree wiring)
  • Protocol or transport issues: inspect internal/transport
  • Auth or login issues: inspect internal/auth, internal/pat, internal/keychain
  • Error message or category issues: inspect internal/errors
  • Audit log issues: inspect internal/audit
  • Plugin loading or command surface: inspect internal/plugin
  • Failure or degraded mode: inspect internal/errors

Policy Checks

When command surface or plugin descriptors change, run:

  • ./scripts/policy/check-command-surface.sh --strict
  • ./scripts/policy/check-open-source-assets.sh

Common Commands

make build
make test
make lint
./scripts/dev/ci-local.sh
git diff --check

Homebrew Formula Delivery

Official releases use the Release workflow's built-in GITHUB_TOKEN to update exactly one tracked Formula after the immutable GitHub assets and their checksums have passed verification. The publisher validates the rendered Ruby, commits only the configured Formula path, never force-pushes main, and retries from a fresh clone up to three times when main advances concurrently. Normal stable and beta releases do not create a Formula PR or run a permission canary. The workflow uses the existing repository-scoped HOMEBREW_PR_TOKEN release identity because GitHub does not allow its built-in Actions App to bypass this repository's rulesets. That identity is the sole user bypass actor on the two default-branch rulesets. The workflow creates the nine Code Admission checks for the Formula-only commit only after proving its sole parent already has all nine successful checks and the committed Formula exactly matches this release's verified bytes.

Keep HOMEBREW_PR_TOKEN repository-scoped with Contents: write and Pull requests: write (the latter remains necessary for withdrawal rollback), keep its owner as the designated ruleset bypass actor, and do not reuse RELEASE_GOVERNANCE_TOKEN. The workflow and publisher provide the Formula-only path restriction; GitHub rulesets do not infer that restriction from the token.

Release Governance and Recovery

Store RELEASE_GOVERNANCE_TOKEN as a dedicated Actions secret with only repository Administration: read. The immutable-releases REST endpoint is an administration setting and cannot be read by the workflow's built-in GITHUB_TOKEN. Both the default-branch governance preflight and the tag contract use this same credential so a missing or expired identity is detected before an irreversible tag is created.

Recovery is restricted to an existing annotated tag whose exact tag object, commit, sealed metadata, original failed run/attempt, requester identity and Release state all match; it then reuses the normal release jobs without a second-person environment approval. A same-run “Re-run failed jobs” is even lighter: the seal job may adopt an existing tag only when its complete authority matches that run and its original attempt is not newer than the current attempt. Do not put publication secrets in temporary branches or create ad-hoc recovery workflows.

Cloud-sealed releases mirror to OSS only when the repository variable ENABLE_OSS_MIRROR is exactly true. Leave the variable unset while no Bucket is provisioned; GitHub, npm, and Homebrew delivery can then complete without running the OSS step. Once enabled, missing credentials, an invalid Bucket, or an upload failure remains fail-closed. The cloud tag immutably records the decision as OSS-Mirror: enabled|deferred; publication and withdrawal consume that sealed value instead of the variable's later state. Deferred releases cannot use repair_oss_version; enabling OSS applies to later release tags until an audited immutable repair marker is implemented.

If an immutable GitHub Release and npm package were delivered but an enabled downstream China mirror failed, dispatch the normal Release workflow from the protected default branch with exactly one of repair_gitee_version or repair_oss_version. Channel repair accepts a fully successful exact release, or a failed exact-tag run only when its latest attempt completed the release contract, build, Apple signature, immutable GitHub publication, and npm delivery checks for the exact tagged commit. OSS repair additionally requires the tag's sealed policy to be enabled. It then downloads and re-verifies the immutable assets before invoking only the selected mirror. For a failed release, an OSS repair requires the OSS step itself to be the recorded failure. A Gitee repair accepts either a failed Gitee job or a Gitee job that was skipped behind that OSS failure; the latter is an explicit Gitee backfill and does not claim that OSS has been repaired. Gitee repair requires GITEE_TOKEN, GITEE_USER, and GITEE_REPO; OSS repair requires OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET, OSS_ENDPOINT, and OSS_BUCKET (with optional OSS_PREFIX) as Actions secrets. Missing credentials fail the selected repair closed.

Handoff Checklist

Before handoff, include:

  1. Changed files and why
  2. Verification commands run and outcomes
  3. Known risks or follow-up work