146 lines
7.0 KiB
Markdown
146 lines
7.0 KiB
Markdown
# 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`, `internal/recovery`
|
|
|
|
## 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
|
|
|
|
```bash
|
|
make build
|
|
make test
|
|
make lint
|
|
./scripts/dev/ci-local.sh
|
|
git diff --check
|
|
```
|
|
|
|
## Homebrew Formula PR Automation
|
|
|
|
Official tag releases require the repository Actions secret
|
|
`HOMEBREW_PR_TOKEN`. Prefer a fine-grained personal access token owned by a
|
|
maintainer or release-bot account, limited to this repository with
|
|
`Contents: write` and `Pull requests: write`. If organization policy prevents
|
|
that account from targeting the repository, use a dedicated classic token with
|
|
only the `public_repo` scope. Do not reuse a broad developer token.
|
|
|
|
Store the dedicated token as the `HOMEBREW_PR_TOKEN` repository Actions secret
|
|
and rotate it before its configured expiration. Replace it immediately if it is
|
|
exposed, its owner loses repository access, or the release-bot ownership
|
|
changes. The Release workflow uses this
|
|
dedicated token only to push an `automation/homebrew-*` branch and open the
|
|
stable or beta Formula PR. It does not push Formula changes directly to `main`.
|
|
The default-branch governance preflight and every tag contract authenticate the
|
|
token before publication, reject over-scoped classic tokens, confirm its
|
|
identity, and run a controlled write canary. The canary pushes a unique
|
|
`automation/homebrew-token-canary-*` branch with a `[skip ci]` commit, creates a
|
|
draft PR, closes it, and deletes the branch with the same token. This proves both
|
|
Contents and Pull requests write access before publication without merging
|
|
anything. The gate also rejects reuse of `RELEASE_GOVERNANCE_TOKEN`.
|
|
No maintainer environment variable is required when creating a tag. Using the
|
|
built-in `GITHUB_TOKEN` is insufficient because organization policy prevents
|
|
Actions from creating pull requests, and its generated PR events may require
|
|
separate workflow approval.
|
|
|
|
## 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.
|
|
|
|
Create a protected `release-recovery` environment limited to protected
|
|
branches, with a required reviewer, self-review disabled, and administrator
|
|
bypass disabled. The workflow reads the environment through the GitHub API and
|
|
fails closed unless the required-reviewer, prevent-self-review, and protected-
|
|
branch rules are present.
|
|
Recovery is restricted to an existing annotated tag whose exact tag object,
|
|
commit, and failed tag-push run all match; it then reuses the normal release
|
|
jobs. 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
|