ci(copilot): optimize cloud agent setup and guidance (#743)

Co-authored-by: Future New (WEILAI LIU) <weilail@microsoft.com>
This commit is contained in:
New Future
2026-09-09 17:37:52 +08:00
committed by GitHub
co-authored by Future New
parent 8e784f6976
commit f454a41ace
6 changed files with 74 additions and 14 deletions
+11 -1
View File
@@ -9,6 +9,12 @@ DDNS is a standard-library-only Dynamic DNS client for Python 2.7 and current Py
5. Run focused checks, then the full affected suite.
6. Self-review the diff and continue through required CI/review feedback until merge-ready.
## Cloud environment
`.github/workflows/copilot-setup-steps.yml` prepares Python, pinned Ruff, Node.js, and locked documentation dependencies. Use the prepared toolchain and run DDNS directly from the repository root; source-based work needs no DDNS installation. If setup failed, a required tool is missing, or a dependency manifest changed, restore the relevant dependencies explicitly.
Read **Source execution and validation** in `AGENTS.md` for the shared Web/MCP service, configuration metadata, static dashboard, and packaging boundaries.
## Canonical commands
```bash
@@ -16,8 +22,10 @@ python -m unittest discover tests -v
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 tests.test_web tests.test_mcp -v
python -m unittest tests.test_web tests.test_mcp tests.test_mcp_http -v
python -m unittest tests.e2e -v
python tools/check.py --providers
python tools/check.py --changed
ruff check .
ruff format --check .
npm --prefix docs ci
@@ -26,6 +34,8 @@ npm --prefix docs run build
Use `tools/AGENTS.md` for Python 3 maintenance tooling. Do not make `tools/` Python 2 compatible unless a task explicitly requires it.
Use focused unittest targets while iterating. `tools/check.py --changed` selects lane checks from committed, staged, unstaged, and untracked changes; set `DDNS_CHECK_BASE_REF` when the comparison base differs from the default branch. It complements, rather than replaces, CI platform and artifact checks.
## Required constraints
- Runtime code under `ddns/`, `run.py`, and tests must retain Python 2.7/3.x compatibility.
+39 -7
View File
@@ -8,12 +8,14 @@ on:
- 'docs/package.json'
- 'docs/package-lock.json'
- 'pyproject.toml'
- 'tools/check.py'
pull_request:
paths:
- '.github/workflows/copilot-setup-steps.yml'
- 'docs/package.json'
- 'docs/package-lock.json'
- 'pyproject.toml'
- 'tools/check.py'
permissions:
contents: read
@@ -25,27 +27,57 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v7
- name: Checkout repository
uses: actions/checkout@v7
- uses: actions/setup-python@v7
- name: Set up Python
uses: actions/setup-python@v7
with:
python-version: '3.12'
- uses: actions/setup-node@v7
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: '24'
cache: npm
cache-dependency-path: docs/package-lock.json
# Explicit restore/save steps keep PR and agent cache access read-only.
package-manager-cache: false
- name: Restore dependency downloads
id: dependency-cache
uses: actions/cache/restore@v6
with:
path: |
~/.cache/pip
~/.npm/_cacache
key: copilot-setup-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.github/workflows/copilot-setup-steps.yml', 'docs/package-lock.json') }}
restore-keys: |
copilot-setup-${{ runner.os }}-${{ runner.arch }}-
- name: Install repository tooling
run: python -m pip install --disable-pip-version-check ruff==0.16.2
- name: Install documentation dependencies
run: npm --prefix docs ci
run: npm --prefix docs ci --prefer-offline --no-audit --no-fund
- name: Report tool versions
- name: Verify development environment
run: |
python --version
ruff --version
node --version
npm --version
python -m ddns --version
python run.py --version
python tools/check.py --help
npm --prefix docs ls --depth=0
- name: Save dependency downloads
if: >-
github.event_name == 'push' &&
github.ref == format('refs/heads/{0}', github.event.repository.default_branch) &&
steps.dependency-cache.outputs.cache-hit != 'true'
uses: actions/cache/save@v6
with:
path: |
~/.cache/pip
~/.npm/_cacache
key: ${{ steps.dependency-cache.outputs.cache-primary-key }}
+1
View File
@@ -10,6 +10,7 @@ on:
- 'AGENTS.md'
- '.agents/**'
- '.github/agents/**'
- '.github/copilot-instructions.md'
- '.github/aw/**'
- '.github/instructions/**'
- '.github/scripts/update_agents_structure.py'
+17 -5
View File
@@ -289,13 +289,23 @@ Classify the task first, then read only the nearest code, tests, docs, and schem
- **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`
- **Web/MCP**: `ddns/web/`, `web/`, `ddns/mcp.py`, `ddns/mcp_http.py`, `ddns/http_config.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/`
- **Agent control plane**: `AGENTS.md`, `.agents/skills/`, `.github/agents/`, `.github/instructions/`
- **Agent control plane**: `AGENTS.md`, `.agents/skills/`, `.github/agents/`, `.github/copilot-instructions.md`, `.github/instructions/`, `tools/`
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.
### Source execution and validation
- Run Python commands from the repository root. `python -m ddns --help` and `python run.py --help` work without installing DDNS or adding runtime dependencies.
- `web/` contains the dashboard's plain HTML/CSS/JavaScript assets, served and packaged by Python. It has no npm build. `docs/` is the separate VitePress site and the only npm project.
- `ddns/web/service.py` shares configuration, status, and synchronization behavior with MCP. `ddns/http_config.py` shares HTTP listener settings between Web and MCP HTTP; cover both callers when changing shared behavior.
- `ddns/config/field-model.json` supplies provider and field metadata to the dashboard and documentation configuration studio. Keep the registry, CLI, latest schema, and bilingual docs aligned; `python tools/check.py --providers` checks provider parity without installing dependencies.
- After focused tests, use `python tools/check.py --changed` for lane-specific checks. It includes merge-base, staged, unstaged, and untracked changes; unknown paths deliberately select all lanes. Set `DDNS_CHECK_BASE_REF` for a non-default comparison base. Use `--all` when a complete cross-lane check is needed, not for every iteration.
- `tests/e2e.py` is an explicit, offline suite and is not included in `unittest discover tests`. Run it separately for CLI, Web, MCP, or shared runtime changes. Sample configurations under `tests/config/` are not a substitute for its loopback fixtures.
- `.github/patch.py` transforms source and packaging metadata in place. Use it only for the relevant build in a disposable checkout, not for ordinary setup, linting, or source tests. Keep real scheduler lifecycle and platform/artifact validation in the appropriate CI environments.
### Useful Commands
```bash
@@ -387,10 +397,12 @@ 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 .
ruff check .
ruff format --check .
```
Inspect proposed lint and formatting fixes and limit them to files touched by the task.
Use these focused targets as a guide:
- Provider: `python -m unittest tests.test_provider_<provider> -v`
@@ -426,7 +438,7 @@ Common checks:
- 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 .`.
- Linting issue: run `ruff check .` and `ruff format --check .`, then review fixes only for the affected files.
```bash
python -m ddns --debug --dns=myprovider --ipv4=test.com
+1 -1
View File
@@ -86,7 +86,7 @@ def lanes_for_path(path: str) -> tuple[str, ...]:
):
lanes.append("Build/Release")
if (
path == "AGENTS.md"
path in ("AGENTS.md", ".github/copilot-instructions.md")
or path.endswith("/AGENTS.md")
or path.startswith(
(".agents/", ".github/agents/", ".github/instructions/", ".github/scripts/", ".github/workflows/", "tools/")
+5
View File
@@ -42,6 +42,11 @@ class LaneSelectionTests(unittest.TestCase):
self.assertEqual(check.lanes_for_path("docs/AGENTS.md"), ("Docs", "Agent/Workflow"))
self.assertEqual(check.lanes_for_path("ddns/provider/AGENTS.md"), ("Provider", "Agent/Workflow"))
def test_copilot_instructions_select_only_agent_lane(self) -> None:
for path in (".github/copilot-instructions.md", r".github\copilot-instructions.md"):
self.assertEqual(check.lanes_for_path(path), ("Agent/Workflow",))
self.assertEqual(check.select_lanes([path])[0], ("Agent/Workflow",))
def test_executable_docs_are_build_changes(self) -> None:
self.assertEqual(check.lanes_for_path("docs/public/install.sh"), ("Docs", "Build/Release"))
self.assertEqual(check.lanes_for_path("docs/esa.js"), ("Docs", "Build/Release"))