🔧 收紧本地脚本与 runner 产物边界

This commit is contained in:
csh 2026-05-22 10:09:58 +08:00
parent 124b953d38
commit 95402f4830
7 changed files with 83 additions and 10 deletions

3
.gitignore vendored
View File

@ -21,3 +21,6 @@ tags
# Environment files
.env
# Runner runtime data
docker-runner/presets/*/runner-data/

View File

@ -26,7 +26,7 @@ Gitea Runner 是 Gitea 的 CI/CD 执行器,类似于 GitLab Runner 或 GitHub Ac
```txt
docker-runner/
├── common/ # 通用脚本(所有版本共用)
│ ├── check_crlf.sh # Windows 换行符检查工具
│ ├── check_crlf.sh # Windows 换行符检查工具(宿主机本地执行)
│ ├── entrypoint.sh # 容器启动脚本
│ ├── setup.sh # Runner 安装脚本
│ ├── upgrade.sh # Runner 升级脚本
@ -50,7 +50,8 @@ docker-runner/
**说明:**
- `common/` 目录中的脚本由所有版本共享,通过 docker-compose.yml 挂载到容器
- `common/` 目录中的脚本由所有版本共享,其中 `entrypoint.sh`、`setup.sh`、`upgrade.sh`、`register.sh`、`manage.sh` 会通过 docker-compose.yml 挂载到容器
- `check_crlf.sh` 是宿主机本地检查工具,用于在构建前修复 `common/` 目录脚本的换行符和执行权限
- `presets/` 目录中每个子目录是一个完整的预设配置,包含 Dockerfile 和 docker-compose.yml
- 数据持久化在 `runner-data/` 目录(自动创建),包含 runner 配置、mirror 缓存和 act_runner 二进制文件
@ -128,7 +129,7 @@ cp .env.example .env
#### 3. (可选)检查换行符
如果从 Windows 复制文件,建议检查换行符:
如果从 Windows 复制文件,建议先在宿主机执行检查工具,修复 `../../common/` 下脚本的换行符和权限:
```bash
../../common/check_crlf.sh

View File

@ -10,6 +10,7 @@ RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# 要检查的文件列表
SCRIPT_FILES=(
@ -31,9 +32,10 @@ echo ""
for file in "${SCRIPT_FILES[@]}"; do
TOTAL_FILES=$((TOTAL_FILES + 1))
file_path="${SCRIPT_DIR}/${file}"
# 检查文件是否存在
if [ ! -f "$file" ]; then
if [ ! -f "${file_path}" ]; then
echo -e "${RED}$file - 文件不存在,跳过${NC}"
continue
fi
@ -42,14 +44,14 @@ for file in "${SCRIPT_FILES[@]}"; do
# 检查换行符
HAS_CRLF=false
if file "$file" | grep -qi "CRLF\|with CR"; then
if file "${file_path}" | grep -qi "CRLF\|with CR"; then
HAS_CRLF=true
NEEDS_FIX=true
fi
# 检查权限
NEEDS_CHMOD=false
if [ ! -x "$file" ]; then
if [ ! -x "${file_path}" ]; then
NEEDS_CHMOD=true
NEEDS_FIX=true
fi
@ -64,13 +66,13 @@ for file in "${SCRIPT_FILES[@]}"; do
# 修复换行符
if [ "$HAS_CRLF" = true ]; then
sed -i 's/\r$//' "$file" 2>/dev/null || sed -i '' 's/\r$//' "$file" 2>/dev/null
sed -i 's/\r$//' "${file_path}" 2>/dev/null || sed -i '' 's/\r$//' "${file_path}" 2>/dev/null
echo -n -e "${YELLOW}[换行符已修复]${NC} "
fi
# 修复权限
if [ "$NEEDS_CHMOD" = true ]; then
chmod +x "$file"
chmod +x "${file_path}"
echo -n -e "${YELLOW}[权限已修复]${NC} "
fi

View File

@ -11,7 +11,6 @@ services:
- ../../common/upgrade.sh:/data/upgrade.sh:ro
- ../../common/register.sh:/data/register.sh:ro
- ../../common/manage.sh:/data/manage.sh:ro
- ../../common/check_crlf.sh:/data/check_crlf.sh:ro
- ../../common/entrypoint.sh:/data/entrypoint.sh:ro
- /var/run/docker.sock:/var/run/docker.sock

View File

@ -11,7 +11,6 @@ services:
- ../../common/upgrade.sh:/data/upgrade.sh:ro
- ../../common/register.sh:/data/register.sh:ro
- ../../common/manage.sh:/data/manage.sh:ro
- ../../common/check_crlf.sh:/data/check_crlf.sh:ro
- ../../common/entrypoint.sh:/data/entrypoint.sh:ro
- /var/run/docker.sock:/var/run/docker.sock

52
tests/check_crlf_test.sh Normal file
View File

@ -0,0 +1,52 @@
#!/bin/bash
set -euo pipefail
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
REPO_ROOT=$(cd "${SCRIPT_DIR}/.." && pwd)
fail() {
echo "FAIL: $*" >&2
exit 1
}
has_crlf() {
local file_path=$1
file "${file_path}" | grep -qi "CRLF\|with CR"
}
test_check_crlf_works_from_preset_directory() {
local temp_root common_dir preset_dir output_file file_name
temp_root=$(mktemp -d)
common_dir="${temp_root}/common"
preset_dir="${temp_root}/preset"
output_file="${temp_root}/output.txt"
mkdir -p "${common_dir}" "${preset_dir}"
cp "${REPO_ROOT}/docker-runner/common/check_crlf.sh" "${common_dir}/check_crlf.sh"
chmod +x "${common_dir}/check_crlf.sh"
for file_name in entrypoint.sh setup.sh upgrade.sh register.sh manage.sh; do
printf '#!/bin/bash\r\necho test\r\n' > "${common_dir}/${file_name}"
chmod 644 "${common_dir}/${file_name}"
done
(
cd "${preset_dir}"
printf 'n\n' | ../common/check_crlf.sh > "${output_file}"
)
! rg -q "文件不存在" "${output_file}" || fail "check_crlf.sh should inspect sibling common scripts even when invoked from preset directory"
for file_name in entrypoint.sh setup.sh upgrade.sh register.sh manage.sh; do
! has_crlf "${common_dir}/${file_name}" || fail "${file_name} should have CRLF fixed"
[ -x "${common_dir}/${file_name}" ] || fail "${file_name} should be made executable"
done
rm -rf "${temp_root}"
}
test_check_crlf_works_from_preset_directory
echo "check_crlf_test.sh: PASS"

View File

@ -55,6 +55,21 @@ test_workflow_docs_and_links_use_actual_paths() {
! rg -q '/\\.github/workflows/' "${release_workflow}" || fail "release workflow should not link to .github/workflows"
}
test_presets_do_not_mount_check_crlf_helper() {
! rg -q 'check_crlf\.sh:/data/check_crlf\.sh:ro' "${REPO_ROOT}/docker-runner/presets" || fail "preset compose files should not mount check_crlf helper into containers"
}
test_runner_data_is_gitignored() {
local path
for path in \
"docker-runner/presets/standard-ubuntu-22/runner-data/config.yaml" \
"docker-runner/presets/buildx-ubuntu-22/runner-data/config.yaml" \
"docker-runner/presets/buildx-archlinux/runner-data/config.yaml"; do
git -C "${REPO_ROOT}" check-ignore -q "${path}" || fail "${path} should be ignored as runtime runner data"
done
}
test_preset_env_examples_exist() {
local file
@ -72,6 +87,8 @@ test_preset_compose_uses_env_for_instance
test_workflows_do_not_hardcode_company_server
test_stats_workflow_uses_workflow_secret_consistently
test_workflow_docs_and_links_use_actual_paths
test_presets_do_not_mount_check_crlf_helper
test_runner_data_is_gitignored
test_preset_env_examples_exist
echo "template_defaults_test.sh: PASS"