Skip to content

Commit c2c5c3c

Browse files
committed
Update copilot-instructions.md
1 parent 4aeb7bb commit c2c5c3c

1 file changed

Lines changed: 154 additions & 42 deletions

File tree

.github/copilot-instructions.md

Lines changed: 154 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,181 @@
1-
# GitHub Copilot Shell Scripting (sh) Review Instructions
1+
# GitHub Copilot Shell Scripting (sh) Review Instructions for acme.sh
22

3-
## 🎯 Overall Goal
3+
## Overall Goal
44

5-
Your role is to act as a rigorous yet helpful senior engineer, reviewing Shell script code (`.sh` files). Ensure the code exhibits the highest levels of robustness, security, and portability.
5+
Your role is to act as a rigorous yet helpful senior engineer, reviewing Shell script code (`.sh` files) for the [acme.sh](https://github.com/acmesh-official/acme.sh) project. Ensure the code exhibits the highest levels of robustness, security, and portability.
66
The review must focus on risks unique to Shell scripting, such as proper quoting, robust error handling, and the secure execution of external commands.
77

8-
## 📝 Required Output Format
8+
## Required Output Format
99

10-
Please adhere to the previous format: organize the feedback into a single, structured report, using the three-level marking system:
10+
Organize the feedback into a single, structured report, using the three-level marking system:
1111

12-
1. **🔴 Critical Issues (Must Fix Before Merge)**
13-
2. **🟡 Suggestions (Improvements to Consider)**
14-
3. **Good Practices (Points to Commend)**
12+
1. **Critical Issues (Must Fix Before Merge)**
13+
2. **Suggestions (Improvements to Consider)**
14+
3. **Good Practices (Points to Commend)**
1515

1616
---
1717

18-
## 🔍 Focus Areas and Rules for Shell
18+
## Shell Compatibility
1919

20-
### 1. Robustness and Error Handling
20+
- **POSIX sh only** -- all scripts must target `sh`, not `bash`. No bash-isms allowed.
21+
- **Shebang**: always use `#!/usr/bin/env sh` (not `#!/bin/sh`, not `#!/usr/bin/env bash`).
22+
- **Use `return`, never `exit`** -- scripts are sourced, not executed as subprocesses. `exit` would kill the parent shell.
23+
- **Cross-platform**: code must work on Linux, macOS, FreeBSD, Solaris, and BusyBox environments.
2124

22-
* **Shebang:** Check that the script starts with the correct Shebang, must be "#!/usr/bin/env sh".
23-
* **Startup Options:** **(🔴 Critical)** Enforce the use of the following combination at the start of the script for safety and robustness:
24-
* `set -e`: Exit immediately if a command exits with a non-zero status.
25-
* `set -u`: Treat unset variables as an error and exit.
26-
* `set -o pipefail`: Ensure the whole pipeline fails if any command in the pipe fails.
27-
* **Exit Codes:** Ensure functions and the main script use `exit 0` for success and a non-zero exit code upon failure.
28-
* **Temporary Files:** Check for the use of `mktemp` when creating temporary files to prevent race conditions and security risks.
25+
---
26+
27+
## Robustness and Error Handling
28+
29+
- **(Critical)** Enforce the use of the following combination at the start of the script for safety and robustness:
30+
- `set -e`: Exit immediately if a command exits with a non-zero status.
31+
- `set -u`: Treat unset variables as an error and exit.
32+
- `set -o pipefail`: Ensure the whole pipeline fails if any command in the pipe fails.
33+
- **Always check return values** of function calls. If an error occurs, there must be a way to stop execution.
34+
- **Return 1** after `_err` messages:
35+
```sh
36+
if [ -z "$VARIABLE" ]; then
37+
_err "VARIABLE is required"
38+
return 1
39+
fi
40+
```
41+
- Check for the use of `mktemp` when creating temporary files to prevent race conditions and security risks.
42+
43+
---
44+
45+
## Security and Quoting
46+
47+
- **(Critical)** Check that all variable expansions (like `$VAR` and `$(COMMAND)`) are properly enclosed in **double quotes** (i.e., `"$VAR"` and `"$(COMMAND)"`) to prevent **Word Splitting** and **Globbing**.
48+
- **(Critical)** Find and flag any hardcoded passwords, keys, tokens, or authentication details.
49+
- Verify that all user input, command-line arguments (`$1`, `$2`, etc.), or environment variables are rigorously validated and sanitized before use.
50+
- Avoid `eval` -- warn against and suggest alternatives, as it can lead to arbitrary code execution.
51+
52+
---
53+
54+
## Use Built-in Helper Functions
55+
56+
Never use raw shell commands when acme.sh provides a wrapper function. This is the most critical rule for portability.
2957

30-
### 2. Security and Quoting
58+
| Instead of | Use |
59+
|---|---|
60+
| `tr '[:upper:]' '[:lower:]'` | `_lower_case()` |
61+
| `head -n 1` | `_head_n 1` |
62+
| `openssl dgst` / `openssl` | `_digest()` / `_hmac()` |
63+
| `date` | `_utc_date()` with `sed`/`tr` |
64+
| `curl` / `wget` | `_get()` or `_post()` |
65+
| `sleep` | `_sleep` |
66+
| `base64` / `openssl base64` | `_base64()` |
67+
| `$(( ))` arithmetic | `_math()` |
68+
| `grep -E` / `grep -Po` | `_egrep_o()` |
69+
| `printf` | `echo` |
70+
| `idn` command | `_idn()` / `_is_idn()` |
3171

32-
* **Variable Quoting:** **(🔴 Critical)** Check that all variable expansions (like `$VAR` and `$(COMMAND)`) are properly enclosed in **double quotes** (i.e., `"$VAR"` and `"$(COMMAND)"`) to prevent **Word Splitting** and **Globbing**.
33-
* **Hardcoded Secrets:** **(🔴 Critical)** Find and flag any hardcoded passwords, keys, tokens, or authentication details.
34-
* **Untrusted Input:** Verify that all user input, command-line arguments (`$1`, `$2`, etc.), or environment variables are rigorously validated and sanitized before use.
35-
* **Avoid `eval`:** Warn against and suggest alternatives to using `eval`, as it can lead to arbitrary code execution.
72+
When fixing a pattern issue, fix **all instances** in the file, not just the one highlighted.
3673

37-
### 3. Readability and Maintainability
74+
---
75+
76+
## Forbidden External Tools
77+
78+
Do not use these commands -- they are not portable across all target platforms:
79+
80+
- `jq` (parse JSON with built-in string manipulation)
81+
- `grep -A` (removed throughout the project)
82+
- `grep -Po` (Perl regex not available everywhere)
83+
- `rev`, `xargs`, `iconv`
84+
- If you must depend on an external tool, check with `_exists` first:
85+
```sh
86+
if ! _exists jq; then
87+
_err "jq is required"
88+
return 1
89+
fi
90+
```
91+
- Warn against patterns like `for i in $(cat file)` or `for i in $(ls)` and recommend the more robust `while IFS= read -r line` pattern for safely processing file contents or filenames that might contain spaces.
92+
93+
---
3894

39-
* **Function Usage:** Recommend wrapping complex or reusable logic within clearly named functions.
40-
* **Local Variables:** Check that variables inside functions are declared using the `local` keyword to avoid unintentionally modifying global state.
41-
* **Naming Convention:** Variable names should use uppercase letters and underscores (e.g., `MY_VARIABLE`), or follow established project conventions.
42-
* **Command Substitution:** Encourage using `$(command)` over backticks `` `command` `` for command substitution, as it is easier to nest and improves readability.
95+
## Configuration Management
4396

44-
### 4. External Commands and Environment
97+
Use the correct save/read functions depending on hook type:
4598

46-
* **`for` Loops:** Warn against patterns like `for i in $(cat file)` or `for i in $(ls)` and recommend the more robust `while IFS= read -r line` pattern for safely processing file contents or filenames that might contain spaces.
47-
* **Use existing acme.sh functions whenever possible.** For example: do not use `tr '[:upper:]' '[:lower:]'`, use `_lower_case` instead.
48-
* **Do not use `head -n`.** Use the `_head_n()` function instead.
49-
* **Do not use `curl` or `wget`.** Use the `_post()` and `_get()` functions instead.
50-
* **Do not use `awk`.** Use the `cut` and `sed` instead.
51-
* **Do not use `[:space:]` or `[:punct:]`.**
52-
* **Do not use `grep -E` or `grep -O`, .** Use the `_egrep_o` function instead.
53-
* **keep it sh compatible, do not use bash-only syntax.** We need to cross platforms between Linux/BSD/Mac.
99+
- **DNS hooks**: `_readaccountconf_mutable` to read API keys, `_saveaccountconf_mutable` to save them. Do not use `_saveaccountconf` or `_readaccountconf`.
100+
- **Deploy hooks**: `_savedeployconf` / `_getdeployconf`
101+
- **Notification hooks**: use account conf functions.
102+
- Save operations should only happen in the correct lifecycle function (e.g., `_issue()`).
103+
- Use environment variables for all configurable values -- do not introduce hardcoded config files.
104+
- Do not clear account conf without a clear reason.
54105

55106
---
56107

57-
### 5. Review Rules for Files Under `dnsapi/`:
108+
## DNS API Conventions
109+
110+
- Read the [DNS API Dev Guide](https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide) before writing a DNS plugin.
111+
- Each file under `dnsapi/` must contain a `{filename}_add` function for adding DNS TXT records.
112+
- The `_get_root()` loop counter `i` must start from `1` (not `2`) to support DNS alias mode.
113+
- The `dns_*_rm()` function must remove records **by TXT value**, not by replacing/updating. See [#1261](https://github.com/acmesh-official/acme.sh/issues/1261).
114+
- Preserve the `dns_*_info` metadata variable block in each DNS script header.
58115

59-
* **Each file must contain a `{filename}_add` function** for adding DNS TXT records. It should use `_readaccountconf_mutable` to read the API key and `_saveaccountconf_mutable` to save it. Do not use `_saveaccountconf` or `_readaccountconf`.
60-
* **keep it shell only** Do not add more dependencies. common tools, such as grep or sed etc are ok to use. do not depend on python or perl etc.
116+
---
61117

62-
## ❌ Things to Avoid
118+
## Variable Naming
63119

64-
* Do not comment on purely stylistic issues like spacing or indentation, which should be handled by tools like ShellCheck or Prettier.
65-
* Do not be overly verbose unless a significant issue is found. Keep feedback concise and actionable.
120+
- Use CamelCase with provider prefix: `KINGHOST_Username` (not `KINGHOST_username`).
121+
- Variable names should use uppercase letters and underscores (e.g., `MY_VARIABLE`), or follow established project conventions.
122+
- Avoid confusingly similar names. Prefer one variable with comma-separated values over multiple variables (e.g., `CZ_Zones` with comma support instead of separate `CZ_Zone` and `CZ_Zones`).
123+
- Do not define variables with the same name in different scopes.
124+
- Variables inside functions should be declared using the `local` keyword to avoid unintentionally modifying global state.
125+
126+
---
66127

128+
## Code Style
67129

130+
- Use `shfmt` for formatting -- CI enforces it.
131+
- Reduce indentation where possible.
132+
- Single space, not double spaces.
133+
- No trailing semicolons after `return` statements.
134+
- Add a newline at the end of every file.
135+
- Use `$(command)` over backticks `` `command` `` for command substitution.
136+
137+
---
138+
139+
## Simplicity
140+
141+
- Prefer hardcoded sensible defaults over unnecessary configuration variables (e.g., use `3600` for TTL instead of a `DESEC_TTL` variable).
142+
- Reject over-engineered solutions. If it can be done in one line, do it in one line.
143+
- Follow existing patterns in the codebase -- new hooks should look like existing hooks.
144+
- Respect user choices: do not `chmod` files that already exist; the user's permissions take priority.
145+
146+
---
147+
148+
## Documentation Requirements
149+
150+
Before a PR can be merged, the following documentation must be provided:
151+
152+
- **Wiki page**: add or update the relevant page:
153+
- DNS APIs: [dnsapi](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) or [dnsapi2](https://github.com/acmesh-official/acme.sh/wiki/dnsapi2)
154+
- Deploy hooks: [deployhooks](https://github.com/acmesh-official/acme.sh/wiki/deployhooks)
155+
- Notification hooks: [notify](https://github.com/acmesh-official/acme.sh/wiki/notify)
156+
- Options: [Options-and-Params](https://github.com/acmesh-official/acme.sh/wiki/Options-and-Params)
157+
- **In-code usage**: add usage examples in the help text of `acme.sh` itself.
158+
- **README**: add website URLs for new DNS providers.
159+
160+
---
161+
162+
## CI and Merge Hygiene
163+
164+
- All CI checks must pass before merge.
165+
- Rebase to the latest `dev` branch frequently -- do not use merge commits.
166+
- Enable GitHub Actions on your fork to catch errors early.
167+
- Run the [DNS API Test](https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test) workflow for DNS plugins.
168+
- For Docker changes, ensure the Dockerfile includes any required dependencies.
169+
170+
---
171+
172+
## Debug Logging
173+
174+
- Use `_debug2` (not `_debug3` or other levels) unless there is a specific reason for a different level.
175+
176+
---
68177

178+
## Things to Avoid in Reviews
69179

180+
- Do not comment on purely stylistic issues like spacing or indentation, which should be handled by tools like ShellCheck or `shfmt`.
181+
- Do not be overly verbose unless a significant issue is found. Keep feedback concise and actionable.

0 commit comments

Comments
 (0)