Skip to content

update ci

update ci #7

Workflow file for this run

name: GitHub Classroom Workflow
on:
push:
branches: [ main ]
paths-ignore:
- 'README.md'
pull_request:
branches: [ main ]
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
TZ: Asia/Shanghai # 设置时区
ENCODED_API_URL: "aHR0cHM6Ly9hcGkubGVhcm5pbmdjYW1wLmNuL3dlYi9hcGkvY291cnNlUmFuay9jcmVhdGVCeVRoaXJk"
jobs:
initialize:
name: Initialize Submodules and Check for Experiments
runs-on: ubuntu-latest
outputs:
run_rustlings: ${{ steps.check.outputs.run_rustlings }}
run_cxx: ${{ steps.check.outputs.run_cxx }}
run_test: ${{ steps.check.outputs.run_test }}
api_url: ${{ steps.decode_api_url.outputs.url }}
run_project2: ${{ steps.check.outputs.run_project2 }}
run_project1: ${{ steps.check.outputs.run_project1 }}
steps:
- uses: actions/checkout@v3
with:
submodules: recursive # 初始化和更新子模块
- name: Decode API URL
id: decode_api_url
run: |
echo "url=$(echo "$ENCODED_API_URL" | base64 --decode)" >> "$GITHUB_OUTPUT"
- name: Check for Rustlings, C++ Experiments and Other Submodules
id: check
run: |
if [ -d "rustlings" ]; then
echo "::set-output name=run_rustlings::true"
else
echo "::set-output name=run_rustlings::false"
fi
if [ -d "learning-cxx" ]; then
echo "::set-output name=run_cxx::true"
else
echo "::set-output name=run_cxx::false"
fi
if [ -d "exams" ]; then
echo "::set-output name=run_test::true"
else
echo "::set-output name=run_test::false"
fi
if [ -d "project1" ]; then
echo "::set-output name=run_project1::true"
else
echo "::set-output name=run_project1::false"
fi
if [ -d "project2" ]; then
echo "::set-output name=run_project2::true"
else
echo "::set-output name=run_project2::false"
fi
rustlings:
name: Rustlings Autograding
needs: initialize
if: ${{ needs.initialize.outputs.run_rustlings == 'true' }}
runs-on: ubuntu-latest
outputs:
details: ${{ steps.autograding.outputs.details }}
points: ${{ steps.autograding.outputs.points}}
env:
API_URL: ${{ needs.initialize.outputs.api_url }}
steps:
- uses: actions/checkout@v3
with:
submodules: 'true'
- name: Set up Rust environment
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true
- name: Install rustlings
run: |
cargo install --force rustlings
rustlings --version
- name: Copy exercises directory to project root
run: cp -r rustlings/exercises .
- name: Run tests for rustlings
run: cargo test --test cicv --verbose
continue-on-error: true
- uses: yfblock/os-autograding@master
id: autograding
with:
outputFile: .github/result/rust_result.json
- name: Generate summary JSON for Rustlings
run: |
outfile=".github/result/rust_result.json"
summary_file=".github/result/rustlings_summary.json"
# 提取需要的值
total_exercations=$(jq '.statistics.total_exercations' $outfile)
total_succeeds=$(jq '.statistics.total_succeeds' $outfile)
github_user="${{ github.actor }}"
# 生成新的 JSON 内容
new_json=$(jq -n \
--arg channel "github" \
--argjson courseId 1700 \
--arg ext "aaa" \
--arg name "$github_user" \
--argjson score "$total_succeeds" \
--argjson totalScore "$total_exercations" \
'{channel: $channel, courseId: $courseId, ext: $ext, name: $name, score: $score, totalScore: $totalScore}')
# 保存新的 JSON 文件
echo "$new_json" > $summary_file
# 打印新的 JSON 文件到终端
cat $summary_file
- name: Post summary JSON to remote API
run: |
summary_file=".github/result/rustlings_summary.json"
# 发送 POST 请求
curl -X POST "$API_URL" \
-H "accept: application/json;charset=utf-8" \
-H "Content-Type: application/json" \
-d "$(cat $summary_file)" \
-v
cxx:
name: C++ Autograding
needs: initialize
if: ${{ needs.initialize.outputs.run_cxx == 'true' }}
runs-on: ubuntu-latest
outputs:
details: ${{ steps.autograding.outputs.details }}
points: ${{ steps.autograding.outputs.points}}
env:
API_URL: ${{ needs.initialize.outputs.api_url }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: 'true'
- name: Install xmake
uses: xmake-io/github-action-setup-xmake@v1
with:
xmake-version: latest
- name: Run tests and save output
run: |
(xmake && xmake run summary) | tee test_output.txt
working-directory: learning-cxx
continue-on-error: true
- name: Parse test results and generate JSON for C++
run: |
outfile="test_output.txt"
summary_file="./../.github/result/cxx_result.json"
# 获取最后一行信息并进行处理
info_line=$(tail -n 1 $outfile | sed 's/\x1b\[[0-9;]*m//g')
# 提取通过题数和总题目数量
total_succeeds=$(echo $info_line | cut -d' ' -f1 | cut -d'/' -f1)
total_exercises=$(echo $info_line | cut -d' ' -f1 | cut -d'/' -f2)
# 提取题目状态字符串
status_string=$(echo $info_line | cut -d' ' -f2 | tr -d '[]')
# 初始化总失败数
total_failures=$((total_exercises - total_succeeds))
# 遍历状态字符串并更新 JSON 中的 result 字段
for (( i=0; i<${#status_string}; i++ )); do
exercise_name=$(printf "exercise%02d" $i)
current_char=${status_string:$i:1}
if [[ $current_char == "#" ]]; then
result="true"
else
result="false"
fi
# 直接修改 JSON 文件中的相应字段
jq --arg name "$exercise_name" --arg result "$result" '.exercises |= map(if .name == $name then .result = ($result | test("true")) else . end)' $summary_file > tmp.json && mv tmp.json $summary_file
done
# 更新统计信息
jq --argjson succeeds "$total_succeeds" --argjson failures "$total_failures" '.statistics.total_succeeds = $succeeds | .statistics.total_failures = $failures' $summary_file > tmp.json && mv tmp.json $summary_file
# 打印新的 JSON 文件到终端
cat $summary_file
working-directory: learning-cxx
continue-on-error: true
- uses: yfblock/os-autograding@master
id: autograding
with:
outputFile: .github/result/cxx_result.json
- name: Generate summary JSON for CXX
run: |
outfile=".github/result/cxx_result.json"
summary_file=".github/result/cxx_summary.json"
# 提取需要的值
total_exercations=$(jq '.statistics.total_exercations' $outfile)
total_succeeds=$(jq '.statistics.total_succeeds' $outfile)
cxx_user="${{ github.actor }}"
# 生成新的 JSON 内容
new_json=$(jq -n \
--arg channel "github" \
--argjson courseId 1699 \
--arg ext "aaa" \
--arg name "$cxx_user" \
--argjson score "$total_succeeds" \
--argjson totalScore "$total_exercations" \
'{channel: $channel, courseId: $courseId, ext: $ext, name: $name, score: $score, totalScore: $totalScore}')
# 保存新的 JSON 文件
echo "$new_json" > $summary_file
# 打印新的 JSON 文件到终端
cat $summary_file
- name: Post summary JSON to remote API
run: |
summary_file=".github/result/cxx_summary.json"
# 发送 POST 请求
curl -X POST "$API_URL" \
-H "accept: application/json;charset=utf-8" \
-H "Content-Type: application/json" \
-d "$(cat $summary_file)" \
-v
test:
name: Test Job for Other Submodules
needs: initialize
if: ${{ needs.initialize.outputs.run_test == 'true' }}
runs-on: ubuntu-latest
env:
API_URL: ${{ needs.initialize.outputs.api_url }}
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
submodules: 'true'
- name: Post summary JSON to remote API
run: |
curl -X POST "$API_URL" \
-H "accept: application/json;charset=utf-8" \
-H "Content-Type: application/json" \
-d '{
"channel": "github",
"courseId": 1698,
"ext": "aaa",
"name": "${{ github.actor }}",
"score": 1,
"totalScore": 23
}' \
-v
project1:
name: Project 1 Autograding
needs: initialize
if: ${{ needs.initialize.outputs.run_project1 == 'true' }}
runs-on: ubuntu-latest
outputs:
details: ${{ steps.autograding.outputs.details }}
points: ${{ steps.autograding.outputs.points}}
env:
API_URL: ${{ needs.initialize.outputs.api_url }}
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
submodules: recursive
- name: Build Project 1
run: |
cd project1
make
- name: Run tests for Project 1
id: run_tests
run: |
make test-cpp | tee test_output.txt
working-directory: project1
continue-on-error: true
- name: Parse test results and generate JSON for Project 1
run: |
test_output="test_output.txt"
json_file="./../.github/result/project1_result.json"
# 初始化计数器
total_exercations=0
total_succeeds=0
total_failures=0
exercises_json="[]"
# 解析输出
while read -r line; do
if [[ "$line" =~ ^[0-9]+/[0-9]+[[:space:]]+Test[[:space:]]+#[0-9]+:[[:space:]]+([a-zA-Z_]+).+(Passed|Failed).*$ ]]; then
test_name="${BASH_REMATCH[1]}"
test_result="${BASH_REMATCH[2]}"
# 计数
total_exercations=$((total_exercations + 1))
if [[ $test_result == "Failed" ]]; then
exercises_json=$(echo "$exercises_json" | jq --arg name "$test_name" --argjson result false '. + [{name: $name, result: $result}]')
total_failures=$((total_failures + 1))
else
exercises_json=$(echo "$exercises_json" | jq --arg name "$test_name" --argjson result true '. + [{name: $name, result: $result}]')
total_succeeds=$((total_succeeds + 1))
fi
fi
done < "$test_output"
# 生成最终 JSON
final_json=$(jq -n \
--argjson exercises "$exercises_json" \
--arg user_name "null" \
--argjson total_exercations "$total_exercations" \
--argjson total_succeeds "$total_succeeds" \
--argjson total_failures "$total_failures" \
--argjson total_time 3 \
'{exercises: $exercises, user_name: $user_name, statistics: {total_exercations: $total_exercations, total_succeeds: $total_succeeds, total_failures: $total_failures, total_time: $total_time}}')
# 保存到 JSON 文件
echo "$final_json" > "$json_file"
# 打印新的 JSON 文件到终端
cat $json_file
working-directory: project1
continue-on-error: true
- uses: yfblock/os-autograding@master
id: autograding
with:
outputFile: .github/result/project1_result.json
- name: Generate summary JSON for Project 1
run: |
outfile=".github/result/project1_result.json"
summary_file=".github/result/project1_summary.json"
# 提取需要的值
total_exercations=$(jq '.statistics.total_exercations' $outfile)
total_succeeds=$(jq '.statistics.total_succeeds' $outfile)
pr1_user="${{ github.actor }}"
new_json=$(jq -n \
--arg channel "github" \
--argjson courseId 1701 \
--arg ext "aaa" \
--arg name "$pr1_user" \
--argjson score "$total_succeeds" \
--argjson totalScore "$total_exercations" \
'{channel: $channel, courseId: $courseId, ext: $ext, name: $name, score: $score, totalScore: $totalScore}')
echo "$new_json" > $summary_file
cat $summary_file
- name: Post summary JSON for Project 1
run: |
summary_file=".github/result/project1_summary.json"
curl -X POST "$API_URL" \
-H "accept: application/json;charset=utf-8" \
-H "Content-Type: application/json" \
-d "$(cat $summary_file)" \
-v
project2:
name: Project 2 Autograding
needs: initialize
if: ${{ needs.initialize.outputs.run_project2 == 'true' }}
runs-on: ubuntu-latest
outputs:
details: ${{ steps.autograding.outputs.details }}
points: ${{ steps.autograding.outputs.points}}
env:
API_URL: ${{ needs.initialize.outputs.api_url }}
steps:
- uses: actions/checkout@v3
with:
submodules: 'true'
- name: Set up Rust environment for Project 2
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true
- name: Build Project 2
run: |
cargo build --verbose
working-directory: project2
continue-on-error: false
- name: Run tests for Project 2
id: run_tests
run: |
cargo test --verbose | tee test_output.txt
working-directory: project2
continue-on-error: true
- name: Parse test results and generate JSON for Project 2
run: |
test_output="test_output.txt"
json_file="./../.github/result/project2_result.json"
# 初始化计数器
total_exercations=0
total_succeeds=0
total_failures=0
exercises_json="["
# 从测试输出中提取测试结果
while IFS= read -r line; do
if [[ $line =~ test\ (.+)\ \.\.\.\ (FAILED|ok) ]]; then
test_name="${BASH_REMATCH[1]}"
test_result="${BASH_REMATCH[2]}"
# 计数
total_exercations=$((total_exercations + 1))
if [[ $test_result == "FAILED" ]]; then
exercises_json+="$(jq -n --arg name "$test_name" --argjson result false '{name: $name, result: $result}'),"
total_failures=$((total_failures + 1))
else
exercises_json+="$(jq -n --arg name "$test_name" --argjson result true '{name: $name, result: $result}'),"
total_succeeds=$((total_succeeds + 1))
fi
fi
done < "$test_output"
# 去掉最后一个逗号并闭合 JSON 数组
exercises_json="${exercises_json%,}]"
# 生成最终 JSON
final_json=$(jq -n \
--argjson exercises "$exercises_json" \
--arg user_name "null" \
--argjson total_exercations "$total_exercations" \
--argjson total_succeeds "$total_succeeds" \
--argjson total_failures "$total_failures" \
--argjson total_time 3 \
'{exercises: $exercises, user_name: $user_name, statistics: {total_exercations: $total_exercations, total_succeeds: $total_succeeds, total_failures: $total_failures, total_time: $total_time}}')
# 保存到 JSON 文件
echo "$final_json" > "$json_file"
# 打印新的 JSON 文件到终端
cat $json_file
working-directory: project2
continue-on-error: true
- uses: yfblock/os-autograding@master
id: autograding
with:
outputFile: .github/result/project2_result.json
- name: Generate summary JSON for Project 2
run: |
outfile=".github/result/project2_result.json"
summary_file=".github/result/project2_summary.json"
# 提取需要的值
total_exercations=$(jq '.statistics.total_exercations' $outfile)
total_succeeds=$(jq '.statistics.total_succeeds' $outfile)
pr2_user="${{ github.actor }}"
# 生成新的 JSON 内容
new_json=$(jq -n \
--arg channel "github" \
--argjson courseId 1699 \
--arg ext "aaa" \
--arg name "$pr2_user" \
--argjson score "$total_succeeds" \
--argjson totalScore "$total_exercations" \
'{channel: $channel, courseId: $courseId, ext: $ext, name: $name, score: $score, totalScore: $totalScore}')
# 保存新的 JSON 文件
echo "$new_json" > $summary_file
# 打印新的 JSON 文件到终端
cat $summary_file
- name: Post summary JSON for Project 2
run: |
summary_file=".github/result/project2_summary.json"
# 发送 POST 请求
curl -X POST "$API_URL" \
-H "accept: application/json;charset=utf-8" \
-H "Content-Type: application/json" \
-d "$(cat $summary_file)" \
-v