mirror of
https://github.com/NewFuture/DDNS.git
synced 2026-10-20 00:16:45 +00:00
* feat(rust): add parallel DDNS MVP Add a synchronous Rust client with compatible configuration, IP discovery, caching, and the first four providers. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): address review compatibility gaps Handle DNSPod failures safely, accept Python-compatible log thresholds, document Rust regex limits, and tolerate non-Unicode environment entries. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): preserve generated provider options Serialize endpoint overrides and --extra.* values so generated configuration files reproduce accepted CLI settings. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): align provider and config behavior Keep provider lookup parameters scoped, continue DNSPod zone discovery safely, and match Python configuration and regex semantics. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): harden credentials and CI scoping Redact provider credentials, align remaining config/cache behavior, and avoid running language-specific builds for unrelated changes while preserving required checks. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): preserve authenticated URL compatibility Translate embedded URL credentials to Basic auth, align generated TTL defaults, and run Rust checks for the abc PR target. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): isolate caches and aggregate safe errors Keep Python cache files untouched, redact retained failures, and continue multi-provider runs after log setup errors. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(rust): complete providers and distribution Port the remaining DNS providers and aliases, add protected native/container release workflows, and provide a checksum-aware Rust installer. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs(agents): register Rust development guide Keep the generated project structure contract aligned with the new bilingual Rust documentation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): address review feedback Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(rust): simplify core design Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(rust): use typed borrowed core Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(rust): streamline transport state Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(rust): share provider fixtures Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(rust): expand end-to-end coverage Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): simplify provider modes and lookup handling Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore(v5): prepare isolated Rust development line Keep Rust changes on the v5 integration line and prepare artifacts without publishing or changing the stable Python entrypoint. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): redact credential-bearing URL paths Hide non-root URL paths in diagnostics and omit URI text from transport errors while preserving actual request URLs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): fully mask credential values Replace credential prefixes and suffixes with a constant opaque marker while retaining raw and percent-encoded masking. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): correct provider signing and zone lookup errors Use RFC3986 canonical queries for Huawei signing. Distinguish documented NameSilo and ClouDNS zone misses from authentication, HTTP, and provider failures. Add offline regressions and matching V5 documentation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): preserve address spelling for regex rules Match regex rules against the extracted address text without IPv6 canonicalization, while retaining strict IpAddr validation and parsed return values. Cover original spelling, invalid candidates, family filtering, and matching boundaries. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): reject unusable local IPs and malformed record lists Filter loopback and unspecified addresses before local indexing. Reject malformed ClouDNS, Huawei, and NameSilo record lookups without creating duplicates while retaining valid empty responses. Isolate installer test globals and cleanup traps in subshells. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): keep DNS.COM signatures out of diagnostics Use the sensitive request path for signed DNS.COM bodies, omit raw HTTP and JSON failure responses, and redact signatures echoed in API messages. Preserve request signing and ordinary HTTP diagnostics with offline regressions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): mask form credentials and validate upgrades before replacement Reuse the form encoder for credential redaction and smoke-test temporary installer binaries before replacing a working installation. Cover rejected upgrades and existing trailing-period IP parsing without changing address extraction. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): preserve provider updates and V5 preparation contracts Send Huawei canonical query bytes unchanged, accept nonempty single-label domains at configuration ingress, and honor AliDNS/ESA extras on unchanged addresses. Require V5 prereleases in artifact preparation with offline regression coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(rust): accept separated negative CLI integers Recognize negative integer tokens as required scalar values without consuming option names. Preserve per-option range validation and cover log-level aliases, inline parity, and real CLI execution. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(ci): use architecture names for Rust QEMU setup Install only the arm64 emulator on the amd64 OCI preparation runner while preserving linux/amd64,linux/arm64 for Buildx. Strengthen offline workflow contracts to distinguish the two inputs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: NewFuture <6290356+NewFuture@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
472 lines
19 KiB
Markdown
472 lines
19 KiB
Markdown
# DDNS Agent Development Guide
|
|
|
|
> Portable project instructions for coding agents. The closest `AGENTS.md` takes precedence.
|
|
|
|
## Table of Contents
|
|
|
|
1. [Project Overview](#project-overview)
|
|
2. [Project Architecture](#project-architecture)
|
|
3. [Agent Development Model](#agent-development-model)
|
|
4. [Testing & Validation](#testing--validation)
|
|
5. [Troubleshooting](#troubleshooting)
|
|
|
|
---
|
|
|
|
## Project Overview
|
|
|
|
### What is DDNS?
|
|
|
|
DDNS is a Python-based Dynamic DNS client that automatically updates DNS records to match the current IP address. It supports:
|
|
|
|
- **Multiple DNS Providers**: 15+ providers including Cloudflare, DNSPod, AliDNS, etc.
|
|
- **Dual Stack**: IPv4 and IPv6 support
|
|
- **Multiple Platforms**: Docker, binary executables, pip installation, and source code
|
|
- **Flexible Configuration**: Command-line arguments, JSON files, and environment variables
|
|
- **Advanced Features**: Multi-domain support, HTTP proxy, caching, scheduled tasks
|
|
|
|
### Key Technologies
|
|
|
|
- **Language**: Python (2.7+ and 3.x compatible)
|
|
- **Testing**: unittest (default) and pytest (optional)
|
|
- **Linting/Formatting**: ruff
|
|
- **CI/CD**: GitHub Actions
|
|
- **Containerization**: Docker (multi-architecture support)
|
|
- **Packaging**: PyPI, Nuitka (for binaries)
|
|
|
|
### Portable Agent Definitions
|
|
|
|
- `AGENTS.md` files contain project and directory rules.
|
|
- `.agents/skills/*/SKILL.md` contains reusable, client-neutral workflows.
|
|
- `.github/agents/*.agent.md` is a thin GitHub Copilot adapter for tool boundaries and role selection.
|
|
- Do not duplicate a Skill in client-specific directories.
|
|
- The default coding agent owns general project work; use a domain agent only when its narrower context is useful.
|
|
|
|
### Project Status
|
|
|
|
- **License**: MIT
|
|
- **Python Versions**: 2.7, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.14
|
|
- **Platforms**: Windows, Linux, macOS
|
|
- **Architectures**: amd64, arm64, arm/v7, arm/v6, 386, ppc64le, riscv64, s390x
|
|
|
|
---
|
|
|
|
## Project Architecture
|
|
|
|
### Directory Structure
|
|
|
|
Here is the folder and file structure for the DDNS project.
|
|
|
|
**Format:** `<TAB depth>{filename}:<TAB>{description}`
|
|
|
|
```text
|
|
.github/: GitHub configuration
|
|
workflows/: CI/CD workflows (build, publish, test)
|
|
instructions/: Agent instructions (python.instructions.md)
|
|
agents/: Thin GitHub Copilot agent profiles
|
|
copilot-instructions.md: GitHub Copilot instructions
|
|
|
|
.agents/: Portable agent workflows
|
|
skills/: Agent Skills specification directories
|
|
|
|
ddns/: Main application code
|
|
__init__.py: Package initialization and version info
|
|
__main__.py: Entry point for module execution
|
|
cache.py: Cache management
|
|
http_config.py: Shared Web and MCP HTTP listener settings
|
|
ip.py: IP address detection logic
|
|
mcp.py: Model Context Protocol helper utilities
|
|
mcp_http.py: MCP Streamable HTTP transport
|
|
|
|
config/: Configuration management
|
|
__init__.py
|
|
cli.py: Command-line argument parsing
|
|
config.py: Configuration loading and merging
|
|
env.py: Environment variable parsing
|
|
file.py: JSON file configuration
|
|
|
|
provider/: DNS provider implementations
|
|
__init__.py: Provider registry
|
|
_base.py: Abstract base classes (SimpleProvider, BaseProvider)
|
|
_signature.py: HMAC signature utilities
|
|
alidns.py: Alibaba Cloud DNS
|
|
aliesa.py: Alibaba Cloud ESA
|
|
callback.py: Custom webhook callbacks
|
|
cloudflare.py: Cloudflare DNS
|
|
cloudns.py: ClouDNS
|
|
debug.py: Debug provider
|
|
dnscom.py: DNS.COM
|
|
dnspod.py: DNSPod (China)
|
|
dnspod_com.py: DNSPod International
|
|
edgeone.py: Tencent EdgeOne
|
|
edgeone_dns.py: Tencent EdgeOne DNS
|
|
he.py: Hurricane Electric
|
|
huaweidns.py: Huawei Cloud DNS
|
|
namesilo.py: NameSilo
|
|
noip.py: No-IP
|
|
tencentcloud.py: Tencent Cloud DNS
|
|
west.py: West.cn DNS
|
|
|
|
scheduler/: Task scheduling implementations
|
|
__init__.py
|
|
_base.py: Base scheduler class
|
|
cron.py: Cron-based scheduler (Linux/macOS)
|
|
launchd.py: macOS launchd scheduler
|
|
schtasks.py: Windows Task Scheduler
|
|
systemd.py: Linux systemd timer
|
|
|
|
util/: Utility modules
|
|
__init__.py
|
|
comment.py: Comment handling
|
|
fileio.py: File I/O operations
|
|
http.py: HTTP client with proxy support
|
|
try_run.py: Safe command execution
|
|
|
|
web/: Embedded management dashboard
|
|
__init__.py: Dashboard package exports
|
|
scheduler.py: In-process dashboard synchronization scheduler
|
|
server.py: Local-only embedded dashboard HTTP server
|
|
service.py: Dashboard data and configuration services
|
|
|
|
tests/: Unit tests
|
|
__init__.py: Test initialization (path setup)
|
|
base_test.py: Shared test utilities and base classes
|
|
README.md: Testing documentation
|
|
config/: Test configuration files
|
|
scripts/: Test helper scripts
|
|
test_cache.py: Cache tests
|
|
test_config_*.py: Configuration tests
|
|
test_ip.py: IP detection tests
|
|
test_mcp_http.py: MCP Streamable HTTP tests
|
|
test_provider_*.py: Provider-specific tests
|
|
test_scheduler_*.py: Scheduler tests
|
|
test_util_*.py: Utility tests
|
|
|
|
docs/: Documentation (VitePress-based)
|
|
AGENTS.md: Documentation-specific agent rules
|
|
.vitepress/: VitePress configuration and theme
|
|
|
|
config/: Configuration documentation (Chinese)
|
|
cli.md: CLI usage guide
|
|
env.md: Environment variables guide
|
|
json.md: JSON configuration guide
|
|
mcp.md: MCP server guide
|
|
|
|
dev/: Developer guides (Chinese)
|
|
provider.md: Provider development guide
|
|
config.md: Configuration system design
|
|
rust.md: Rust client development guide
|
|
|
|
providers/: Provider-specific documentation (Chinese)
|
|
README.md: Provider list and overview
|
|
51dns.md: 51DNS provider guide
|
|
alidns.md: Alibaba Cloud DNS guide
|
|
aliesa.md: Alibaba Cloud ESA guide
|
|
callback.md: Custom webhook callbacks guide
|
|
cloudflare.md: Cloudflare DNS guide
|
|
cloudns.md: ClouDNS guide
|
|
debug.md: Debug provider guide
|
|
dnscom.md: DNS.COM provider guide
|
|
dnspod.md: DNSPod (China) guide
|
|
dnspod_com.md: DNSPod International guide
|
|
edgeone.md: Tencent EdgeOne guide
|
|
edgeone_dns.md: Tencent EdgeOne DNS guide
|
|
he.md: Hurricane Electric guide
|
|
huaweidns.md: Huawei Cloud DNS guide
|
|
namesilo.md: NameSilo guide
|
|
noip.md: No-IP guide
|
|
tencentcloud.md: Tencent Cloud DNS guide
|
|
west.md: West.cn DNS guide
|
|
|
|
en/: English documentation
|
|
config/: English configuration guides (mirrors config/)
|
|
dev/: English developer guides (mirrors dev/)
|
|
providers/: English provider guides (mirrors providers/)
|
|
docker.md: Docker documentation
|
|
install.md: Installation guide
|
|
|
|
public/: Public static assets
|
|
img/: Images and diagrams
|
|
schema/: JSON schema files (symlink)
|
|
tests/: Test configuration examples
|
|
|
|
docker.md: Docker documentation (Chinese)
|
|
install.md: Installation guide (Chinese)
|
|
release.md: Release notes (Chinese)
|
|
|
|
docker/: Docker configuration
|
|
Dockerfile: Main Dockerfile
|
|
glibc.Dockerfile: glibc-based build
|
|
musl.Dockerfile: musl-based build
|
|
entrypoint.sh: Container entrypoint script
|
|
|
|
schema/: JSON schemas
|
|
v2.json: Legacy schema v2
|
|
v2.8.json: Legacy schema v2.8
|
|
v4.0.json: Previous schema v4.0
|
|
v4.1.json: Latest schema v4.1
|
|
|
|
tools/: Python 3.12+ repository maintenance tools
|
|
run.py: Direct run script
|
|
pyproject.toml: Python project configuration
|
|
setup.cfg: Setup configuration
|
|
.gitignore: Git ignore rules
|
|
LICENSE: MIT License
|
|
README.md: Main README (Chinese)
|
|
README.en.md: Main README (English)
|
|
```
|
|
|
|
### Module Dependencies
|
|
|
|
```text
|
|
ddns/__main__.py
|
|
├── ddns.config.* # Configuration loading
|
|
│ ├── cli # Command-line parsing
|
|
│ ├── env # Environment variables
|
|
│ ├── file # JSON file loading
|
|
│ └── config # Config merging and validation
|
|
│
|
|
├── ddns.ip # IP address detection
|
|
│ └── ddns.util.http # HTTP client for public IP APIs
|
|
│
|
|
├── ddns.provider.* # DNS provider implementations
|
|
│ ├── _base # Base classes (SimpleProvider, BaseProvider)
|
|
│ ├── _signature # HMAC signature for cloud APIs
|
|
│ └── ddns.util.http # HTTP client for API requests
|
|
│
|
|
├── ddns.cache # Caching to reduce API calls
|
|
│ └── ddns.util.fileio # File operations
|
|
│
|
|
└── ddns.scheduler.* # Task scheduling
|
|
└── ddns.util.try_run # Safe command execution
|
|
```
|
|
|
|
### Core Components
|
|
|
|
#### 1. Provider System
|
|
|
|
- **BaseProvider**: Full CRUD DNS provider (query, create, update records)
|
|
- Used by: Cloudflare, AliDNS, DNSPod, TencentCloud, EdgeOne, etc.
|
|
- Features: Automatic zone detection, record management, caching support
|
|
|
|
- **SimpleProvider**: Simple update-only DNS provider
|
|
- Used by: HE.net, No-IP, Debug, Callback
|
|
- Features: Direct record updates without querying
|
|
|
|
#### 2. Configuration System
|
|
|
|
Three-layer priority system:
|
|
1. **Command-line arguments** (highest priority) - via `ddns.config.cli`
|
|
2. **JSON configuration files** - via `ddns.config.file`
|
|
3. **Environment variables** (lowest priority) - via `ddns.config.env`
|
|
|
|
#### 3. IP Detection System
|
|
|
|
Multiple methods supported (via `ddns.ip`):
|
|
- Network interface (by index number)
|
|
- Default route IP
|
|
- Public IP (via external APIs)
|
|
- URL-based (custom API endpoint)
|
|
- Regex matching (from ifconfig/ipconfig output)
|
|
- Command execution (custom script)
|
|
- Shell execution (system shell command)
|
|
|
|
#### 4. Scheduler System
|
|
|
|
Platform-specific implementations:
|
|
- **Linux**: systemd timers or cron
|
|
- **macOS**: launchd or cron
|
|
- **Windows**: Task Scheduler (schtasks)
|
|
- **Docker**: Built-in cron with configurable intervals
|
|
|
|
---
|
|
|
|
## Agent Development Model
|
|
|
|
### Agent Quick Start
|
|
|
|
Classify the task first, then read only the nearest code, tests, docs, and schema for that lane.
|
|
|
|
- **Provider**: `ddns/provider/`, `tests/test_provider_*.py`, `docs/providers/`, `docs/en/providers/`
|
|
- **Config/schema**: `ddns/config/`, `schema/`, `tests/test_config_*.py`, `docs/config/`, `docs/en/config/`
|
|
- **IP/HTTP**: `ddns/ip.py`, `ddns/util/http.py`, `tests/test_ip.py`, `tests/test_util_http*.py`
|
|
- **Scheduler**: `ddns/scheduler/`, `tests/test_scheduler_*.py`
|
|
- **Web/MCP**: `ddns/web/`, `web/`, `ddns/mcp.py`, `tests/test_web.py`, `tests/test_mcp.py`
|
|
- **Docs**: `README*.md`, `docs/`, `docs/AGENTS.md`
|
|
- **Build/release**: `pyproject.toml`, `run.py`, `.github/patch.py`, `docker/`, `.github/workflows/`
|
|
- **Rust V5**: `rust/`, `rust/tests/`, `docs/dev/rust.md`, `docs/en/dev/rust.md`; target the `v5` integration branch
|
|
- **Agent control plane**: `AGENTS.md`, `.agents/skills/`, `.github/agents/`, `.github/instructions/`
|
|
|
|
Use `rg` / `rg --files` for discovery, make narrow edits, validate the touched behavior, and report any command that could not run. A task is complete only when code, tests, schemas, docs, and generated metadata affected by the behavior are consistent.
|
|
|
|
### Useful Commands
|
|
|
|
```bash
|
|
python -m ddns --help
|
|
python run.py --help
|
|
pip install ddns
|
|
ddns --help
|
|
docker run --rm newfuture/ddns:latest --help
|
|
curl -fsSL https://ddns.newfuture.cc/install.sh | sh
|
|
python -m ddns -c config.json
|
|
python -m ddns --dns=cloudflare --id=EMAIL --token=TOKEN --ipv4=domain.com
|
|
python -m ddns --debug
|
|
python -m ddns --dns=debug --ipv4=test.com --debug
|
|
ddns task --install 5
|
|
ddns task --enable
|
|
```
|
|
|
|
Linux/macOS scheduled tasks use systemd, cron, or launchd; Windows uses the release binary and `ddns task --install 5`.
|
|
|
|
---
|
|
|
|
## Development Rules
|
|
|
|
### Hard Rules
|
|
|
|
Follow `.github/instructions/python.instructions.md` for shipped Python and tests. Follow `tools/AGENTS.md` for maintenance tooling.
|
|
|
|
- Use only standard-library runtime dependencies.
|
|
- Preserve Python 2.7 and 3.x compatibility: no f-strings, annotations, async/await, or Python 3-only syntax.
|
|
- Use type comments, for example `# type: (...) -> ReturnType`.
|
|
- Keep CLI flags, provider names, config keys, schemas, and cache behavior backward compatible unless explicitly asked otherwise.
|
|
- Do not reformat unrelated files or modernize stable code for style alone.
|
|
|
|
### Change Flow
|
|
|
|
1. Start from an approved issue, feature, or maintenance goal.
|
|
2. Read the closest implementation, tests, docs, schema, and `AGENTS.md`.
|
|
3. State the implementation plan, compatibility impact, and acceptance checks.
|
|
4. Mirror established patterns instead of inventing new abstractions.
|
|
5. Change code, tests, schemas, bilingual docs, and metadata together.
|
|
6. Run focused validation first, then the full affected suite.
|
|
7. Self-review the diff for unrelated edits, secrets, compatibility, and missing artifacts.
|
|
8. Continue through CI and review feedback until merge-ready or escalate with evidence.
|
|
|
|
### Definition of Done by Lane
|
|
|
|
| Lane | Required artifacts | Required evidence |
|
|
|---|---|---|
|
|
| Core IP/HTTP/cache | implementation, regression tests, offline fixtures, behavior docs | focused unit tests, offline E2E, Python matrix |
|
|
| Config/schema/CLI | parser behavior, field model, latest schema, Chinese/English docs | config tests, schema checks, docs build |
|
|
| Provider | implementation, registry/aliases, field model, tests, schema, bilingual docs, navigation | provider/base tests, provider consistency check, docs build |
|
|
| Web | service/API, static assets, auth/scheduler behavior, package resources | Web tests, Web E2E, wheel/sdist install |
|
|
| Scheduler/install | OS implementation, CLI, lifecycle scripts, install docs | platform and install matrices |
|
|
| MCP | protocol behavior, schemas/annotations, lifecycle, redaction, docs | MCP tests, modern/legacy E2E, package/binary tests |
|
|
| Docs/site | Chinese/English parity, links, navigation, examples, `llms.txt` | documentation contracts and VitePress build |
|
|
| Build/release | transformations, artifacts, matrices, release notes | package/binary/container checks and protected rehearsal |
|
|
| Agent/workflow | instructions, permissions, validation logic | agent contracts and human review |
|
|
|
|
### Rust V5 Development
|
|
|
|
- Keep Python maintenance on `master` / `v4`; target Rust feature PRs at `v5`.
|
|
- Preserve `rust/` and the `ddns-rs` command while V5 is under development.
|
|
- Use a V5 prerelease version and keep `rust/Cargo.toml` and `rust/Cargo.lock` aligned.
|
|
- V5 preparation produces Actions artifacts only. Do not create public V5 tags,
|
|
releases, registry images, or stable-site deployments as part of branch preparation.
|
|
- Before the first public V5 tag, separate Python/Rust installer and download
|
|
selectors and obtain explicit direction for the Rust publication workflow.
|
|
|
|
### Provider Changes
|
|
|
|
- Use `BaseProvider` for query/create/update APIs and `SimpleProvider` for update-only APIs.
|
|
- Register new providers in `ddns/provider/__init__.py`.
|
|
- Update canonical metadata in `ddns/config/field-model.json`.
|
|
- Add mocked tests in `tests/test_provider_<provider>.py`; never require real credentials or live provider APIs.
|
|
- Update both `docs/providers/<provider>.md` and `docs/en/providers/<provider>.md`.
|
|
- Update both latest schema enums, CLI choices, provider indexes, navigation, and `docs/llms.txt`.
|
|
- See `docs/dev/provider.md` and `docs/en/dev/provider.md` for full provider method signatures.
|
|
- Follow `ddns/provider/AGENTS.md` and `.agents/skills/provider-development/SKILL.md`.
|
|
|
|
### Documentation
|
|
|
|
Keep Chinese and English docs aligned. Preserve code blocks, option names, JSON keys, CLI flags, and provider IDs exactly across translations. Link Chinese docs to Chinese pages and English docs to `docs/en/` pages.
|
|
|
|
Follow `docs/AGENTS.md` and `.agents/skills/documentation-maintenance/SKILL.md`. Treat `docs/public/install.sh` and `docs/esa.js` as executable, high-risk files rather than ordinary prose.
|
|
|
|
### Build and Release
|
|
|
|
Read the current workflows and Dockerfiles instead of relying on remembered versions or matrices. Do not publish, access release credentials, weaken required checks, disable caches, or remove platform coverage. Follow `.agents/skills/build-release-maintenance/SKILL.md`.
|
|
|
|
---
|
|
|
|
## Testing & Validation
|
|
|
|
Run the smallest useful test first, then broaden when shared behavior changed.
|
|
|
|
```bash
|
|
python -m unittest tests.test_provider_cloudflare -v
|
|
python -m unittest tests.test_config_config -v
|
|
python -m unittest tests.test_ip -v
|
|
python -m unittest discover tests -v
|
|
python -m pytest tests/ -v # optional, when pytest is installed
|
|
ruff check --fix --unsafe-fixes .
|
|
ruff format .
|
|
```
|
|
|
|
Use these focused targets as a guide:
|
|
|
|
- Provider: `python -m unittest tests.test_provider_<provider> -v`
|
|
- Config/schema: `python -m unittest discover tests -p "test_config*.py" -v`
|
|
- IP/HTTP: `python -m unittest tests.test_ip tests.test_util_http tests.test_util_http_retry tests.test_util_http_proxy_list -v`
|
|
- Scheduler: `python -m unittest tests.test_scheduler_<name> -v`
|
|
- Broad shared change: `python -m unittest discover tests -v`
|
|
|
|
For touched files or examples:
|
|
|
|
```bash
|
|
python -m py_compile ddns/provider/myprovider.py
|
|
python -m json.tool config.json
|
|
```
|
|
|
|
Provider tests should import from `base_test`; other tests should import from `tests/__init__.py`. Mock HTTP calls and assert request details, response parsing, and error handling.
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
1. Reproduce with the smallest command, fixture, or unit test.
|
|
2. Locate the layer: config parsing, IP detection, provider mapping, HTTP transport, cache, or scheduler.
|
|
3. Read the nearest passing test and nearest similar implementation.
|
|
4. Fix root cause, add a regression test when behavior changed, and re-run focused validation.
|
|
|
|
Common checks:
|
|
|
|
- Import error: file exists, provider registered, test path setup uses `tests/__init__.py` or `tests/base_test.py`.
|
|
- Syntax error: remove Python 3-only syntax and keep Python 2.7 compatibility.
|
|
- Auth/signature issue: verify credential shape and signing with mocked tests; never print real tokens.
|
|
- Record not updated: inspect cache, record type, line, TTL, domain split, and provider response parsing.
|
|
- Proxy/network issue: compare with `ddns/util/http.py`; use `--proxy=DIRECT` or `--ssl=false` only as diagnostics.
|
|
- Schema mismatch: update `schema/v4.1.json` and matching config tests together.
|
|
- Test failure: inspect mock return values and `mock_http.call_args`.
|
|
- Linting issue: run `ruff check --fix --unsafe-fixes .` and `ruff format .`.
|
|
|
|
```bash
|
|
python -m ddns --debug --dns=myprovider --ipv4=test.com
|
|
python -m ddns --debug --log_file=debug.log
|
|
python -m ddns --dns=debug --ipv4=test.com --debug
|
|
rm -f /tmp/ddns.cache
|
|
```
|
|
|
|
Use cache removal only when debugging stale local state. Avoid destructive git recovery unless the user explicitly requests it.
|
|
|
|
---
|
|
|
|
## Safety and Escalation
|
|
|
|
- Prefer small, reviewable changes that follow existing patterns.
|
|
- Fix root causes and add tests for regressions.
|
|
- Preserve user changes in the working tree; never reset or reformat unrelated files.
|
|
- Treat configs, logs, environment variables, API tokens, and provider credentials as sensitive.
|
|
- Prefer mocked or dry-run validation; ask before using real credentials, provider APIs, or scheduler installation on a host.
|
|
- Use structured parsers for JSON, URLs, and HTTP data.
|
|
- Refactor only when it directly supports the task or removes clear local duplication.
|
|
- Require human direction for file/provider/config-key renames, compatibility breaks, security policy, workflow permissions, credentials, and publication.
|
|
- For large changes, explain goal, alternatives, impact, validation plan, and rollback before implementation.
|
|
- When asked to commit or draft PR text, use conventional commits such as `fix(util.http): handle proxy errors`.
|
|
|
|
---
|
|
|
|
**Version**: 1.1.0
|
|
**Last Updated**: 2026-08-25
|
|
**Maintained by**: DDNS Project Contributors
|