Skip to content

Commit f2da86f

Browse files
author
William Yang
committed
feat: add Docker image support for local testing and CI/CD
- Add Dockerfile for bootcs-cli base image - Add bootcs-evaluate.sh script for standardized evaluation - Add GitHub Actions workflow for building and pushing images - Update README with Docker usage instructions
1 parent 0e70f20 commit f2da86f

File tree

4 files changed

+235
-0
lines changed

4 files changed

+235
-0
lines changed

.github/workflows/docker.yml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: Build and Push Docker Image
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ['v*']
7+
pull_request:
8+
branches: [main]
9+
10+
env:
11+
REGISTRY: ghcr.io
12+
IMAGE_NAME: ${{ github.repository }}
13+
14+
jobs:
15+
build:
16+
runs-on: ubuntu-latest
17+
permissions:
18+
contents: read
19+
packages: write
20+
21+
steps:
22+
- name: Checkout repository
23+
uses: actions/checkout@v4
24+
25+
- name: Set up Docker Buildx
26+
uses: docker/setup-buildx-action@v3
27+
28+
- name: Log in to Container Registry
29+
if: github.event_name != 'pull_request'
30+
uses: docker/login-action@v3
31+
with:
32+
registry: ${{ env.REGISTRY }}
33+
username: ${{ github.actor }}
34+
password: ${{ secrets.GITHUB_TOKEN }}
35+
36+
- name: Extract metadata
37+
id: meta
38+
uses: docker/metadata-action@v5
39+
with:
40+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
41+
tags: |
42+
type=ref,event=branch
43+
type=ref,event=pr
44+
type=semver,pattern={{version}}
45+
type=semver,pattern={{major}}.{{minor}}
46+
type=sha,prefix=
47+
type=raw,value=latest,enable={{is_default_branch}}
48+
49+
- name: Build and push
50+
uses: docker/build-push-action@v5
51+
with:
52+
context: .
53+
push: ${{ github.event_name != 'pull_request' }}
54+
tags: ${{ steps.meta.outputs.tags }}
55+
labels: ${{ steps.meta.outputs.labels }}
56+
cache-from: type=gha
57+
cache-to: type=gha,mode=max
58+
59+
test:
60+
runs-on: ubuntu-latest
61+
needs: build
62+
if: github.event_name != 'pull_request'
63+
64+
steps:
65+
- name: Checkout repository
66+
uses: actions/checkout@v4
67+
68+
- name: Test Docker image
69+
run: |
70+
docker run --rm ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest --version
71+
echo "Docker image test passed!"

Dockerfile

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# bootcs-cli Docker Image
2+
# 用于本地自测和 GitHub Actions 评测
3+
4+
FROM python:3.11-slim
5+
6+
LABEL org.opencontainers.image.source="https://github.com/bootcs-cn/bootcs-cli"
7+
LABEL org.opencontainers.image.description="BootCS CLI for code checking and evaluation"
8+
LABEL org.opencontainers.image.licenses="GPL-3.0"
9+
10+
# 安装系统依赖
11+
RUN apt-get update && apt-get install -y --no-install-recommends \
12+
build-essential \
13+
clang \
14+
gcc \
15+
git \
16+
make \
17+
valgrind \
18+
&& rm -rf /var/lib/apt/lists/*
19+
20+
# 设置工作目录
21+
WORKDIR /app
22+
23+
# 复制项目文件
24+
COPY pyproject.toml README.md LICENSE ./
25+
COPY bootcs/ ./bootcs/
26+
27+
# 安装 bootcs
28+
RUN pip install --no-cache-dir -e .
29+
30+
# 创建工作目录
31+
WORKDIR /workspace
32+
33+
# 入口点
34+
ENTRYPOINT ["python", "-m", "bootcs"]
35+
CMD ["--help"]

README.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ BootCS 命令行工具 - 用于代码检查和提交
1818

1919
## 安装
2020

21+
### 方式一:Python 安装
22+
2123
```bash
2224
# 开发模式安装
2325
git clone https://github.com/bootcs-cn/bootcs-cli.git
@@ -27,6 +29,16 @@ source .venv/bin/activate
2729
pip install -e .
2830
```
2931

32+
### 方式二:Docker 镜像
33+
34+
```bash
35+
# 拉取基础镜像
36+
docker pull ghcr.io/bootcs-cn/bootcs-cli:latest
37+
38+
# 拉取包含 CS50 检查脚本的镜像
39+
docker pull ghcr.io/bootcs-cn/bootcs-cli:cs50
40+
```
41+
3042
## 快速开始
3143

3244
### 1. 登录
@@ -102,6 +114,71 @@ bootcs logout
102114
| `-m, --message MSG` | 自定义提交消息 |
103115
| `-y, --yes` | 跳过确认提示 |
104116

117+
## Docker 使用
118+
119+
### 本地自测
120+
121+
使用 Docker 镜像可以在本地快速进行代码检查,无需安装 Python 环境:
122+
123+
```bash
124+
# 使用基础镜像检查代码
125+
docker run --rm -v $(pwd):/workspace -v /path/to/checks:/checks \
126+
ghcr.io/bootcs-cn/bootcs-cli:latest \
127+
check course-cs50/hello --local /checks/hello
128+
129+
# 使用课程专用镜像(已包含检查脚本)
130+
docker run --rm -v $(pwd):/workspace \
131+
ghcr.io/bootcs-cn/bootcs-cli:cs50 \
132+
check course-cs50/hello --local /checks/hello
133+
```
134+
135+
### GitHub Actions 评测
136+
137+
在 GitHub Actions 中使用 Docker 镜像进行自动评测:
138+
139+
```yaml
140+
# .github/workflows/evaluate.yml
141+
name: Evaluate
142+
143+
on:
144+
push:
145+
branches: [main]
146+
147+
jobs:
148+
evaluate:
149+
runs-on: ubuntu-latest
150+
container:
151+
image: ghcr.io/bootcs-cn/bootcs-cli:cs50
152+
steps:
153+
- uses: actions/checkout@v4
154+
- name: Run check
155+
run: |
156+
bootcs check course-cs50/hello --local /checks/hello --output json > result.json
157+
- name: Upload result
158+
uses: actions/upload-artifact@v4
159+
with:
160+
name: result
161+
path: result.json
162+
```
163+
164+
### 使用评测脚本
165+
166+
镜像中包含 `bootcs-evaluate.sh` 脚本,用于标准化评测:
167+
168+
```bash
169+
# 脚本用法
170+
bootcs-evaluate.sh <slug> <checks_path> <student_code_path>
171+
172+
# 示例
173+
docker run --rm \
174+
-v $(pwd):/workspace \
175+
-v /path/to/output:/output \
176+
ghcr.io/bootcs-cn/bootcs-cli:cs50 \
177+
bootcs-evaluate.sh course-cs50/hello /checks/hello /workspace
178+
179+
# 结果输出到 /output/result.json
180+
```
181+
105182
## 开发
106183

107184
```bash

scripts/bootcs-evaluate.sh

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/bin/bash
2+
# bootcs-evaluate.sh - 评测入口脚本
3+
# 用于 GitHub Actions 评测 workflow
4+
5+
set -e
6+
7+
# 参数
8+
SLUG="${1:-}"
9+
CHECKS_PATH="${2:-/checks}"
10+
STUDENT_CODE_PATH="${3:-/workspace}"
11+
12+
if [ -z "$SLUG" ]; then
13+
echo "Usage: bootcs-evaluate.sh <slug> [checks_path] [student_code_path]"
14+
echo "Example: bootcs-evaluate.sh course-cs50/hello /checks /workspace"
15+
exit 1
16+
fi
17+
18+
# 解析 slug
19+
COURSE=$(echo "$SLUG" | cut -d'/' -f1)
20+
STAGE=$(echo "$SLUG" | cut -d'/' -f2)
21+
22+
# 检查目录
23+
CHECK_DIR="${CHECKS_PATH}/${STAGE}"
24+
if [ ! -d "$CHECK_DIR" ]; then
25+
echo "Error: Check directory not found: $CHECK_DIR"
26+
exit 1
27+
fi
28+
29+
# 切换到学生代码目录
30+
cd "$STUDENT_CODE_PATH"
31+
32+
echo "========================================"
33+
echo "BootCS Evaluation"
34+
echo "========================================"
35+
echo "Slug: $SLUG"
36+
echo "Check Dir: $CHECK_DIR"
37+
echo "Working Dir: $(pwd)"
38+
echo "========================================"
39+
echo ""
40+
41+
# 运行检查
42+
python -m bootcs check "$SLUG" --local "$CHECK_DIR" --output json
43+
44+
# 获取退出码
45+
EXIT_CODE=$?
46+
47+
echo ""
48+
echo "========================================"
49+
echo "Evaluation completed with exit code: $EXIT_CODE"
50+
echo "========================================"
51+
52+
exit $EXIT_CODE

0 commit comments

Comments
 (0)