Skip to content

Calculate Student Score #50

Calculate Student Score

Calculate Student Score #50

name: Calculate Student Score
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened]
branches:
- main
jobs:
calculate-score:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup jq
run: |
sudo apt-get update
sudo apt-get install -y jq
- name: Check for student's article
id: check_article
run: |
# 确定要检测的仓库和学员用户名
if [ "${{ github.event_name }}" = "pull_request" ]; then
# PR 事件:检测 PR 来源仓库(学员 Fork 的仓库)
CHECK_OWNER=${{ github.event.pull_request.head.repo.owner.login }}
CHECK_REPO=${{ github.event.pull_request.head.repo.name }}
STUDENT_NAME=${{ github.actor }}
echo "PR 模式:检测仓库 $CHECK_OWNER/$CHECK_REPO,学员 $STUDENT_NAME"
else
# 非 PR 事件:检测当前仓库
REPO_NAME=${{ github.repository }}
CHECK_OWNER=$(echo $REPO_NAME | cut -d'/' -f1)
CHECK_REPO=$(echo $REPO_NAME | cut -d'/' -f2)
STUDENT_NAME=$CHECK_OWNER
echo "非 PR 模式:检测仓库 $CHECK_OWNER/$CHECK_REPO,学员 $STUDENT_NAME"
fi
ARTICLE_EXISTS=0
CONTENTS_RESPONSE=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/$CHECK_OWNER/$CHECK_REPO/contents")
if echo "$CONTENTS_RESPONSE" | jq -r '.[].name' | grep -q "^$STUDENT_NAME\.md$"; then
ARTICLE_EXISTS=1
echo "Found article file: $STUDENT_NAME.md"
else
echo "No article file named $STUDENT_NAME.md found"
fi
echo "article_exists=$ARTICLE_EXISTS" >> $GITHUB_ENV
echo "student_name=$STUDENT_NAME" >> $GITHUB_ENV
if [ $ARTICLE_EXISTS -eq 1 ]; then
ARTICLE_BONUS=20
else
ARTICLE_BONUS=0
fi
echo "article_bonus=$ARTICLE_BONUS" >> $GITHUB_ENV
- name: Check for lesson assignments
id: check_lessons
if: github.event_name == 'pull_request'
run: |
# PR 事件:检测 PR 来源仓库(学员 Fork 的仓库)
CHECK_OWNER=${{ github.event.pull_request.head.repo.owner.login }}
CHECK_REPO=${{ github.event.pull_request.head.repo.name }}
STUDENT_NAME=${{ github.actor }}
echo "检测学员 $STUDENT_NAME 在仓库 $CHECK_OWNER/$CHECK_REPO 中的作业"
LESSON1_EXISTS=0
LESSON2_EXISTS=0
# Check lesson1 assignment
LESSON1_RESPONSE=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/$CHECK_OWNER/$CHECK_REPO/contents/assignments/lesson1")
if echo "$LESSON1_RESPONSE" | jq -r '.[].name' 2>/dev/null | grep -q "^$STUDENT_NAME\.md$"; then
LESSON1_EXISTS=1
echo "Found lesson1 assignment: assignments/lesson1/$STUDENT_NAME.md"
else
echo "No lesson1 assignment found for $STUDENT_NAME"
fi
# Check lesson2 assignment
LESSON2_RESPONSE=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/$CHECK_OWNER/$CHECK_REPO/contents/assignments/lesson2")
if echo "$LESSON2_RESPONSE" | jq -r '.[].name' 2>/dev/null | grep -q "^$STUDENT_NAME\.md$"; then
LESSON2_EXISTS=1
echo "Found lesson2 assignment: assignments/lesson2/$STUDENT_NAME.md"
else
echo "No lesson2 assignment found for $STUDENT_NAME"
fi
echo "lesson1_exists=$LESSON1_EXISTS" >> $GITHUB_ENV
echo "lesson2_exists=$LESSON2_EXISTS" >> $GITHUB_ENV
if [ $LESSON1_EXISTS -eq 1 ]; then
LESSON1_SCORE=10
else
LESSON1_SCORE=0
fi
if [ $LESSON2_EXISTS -eq 1 ]; then
LESSON2_SCORE=10
else
LESSON2_SCORE=0
fi
echo "lesson1_score=$LESSON1_SCORE" >> $GITHUB_ENV
echo "lesson2_score=$LESSON2_SCORE" >> $GITHUB_ENV
- name: Calculate score based on GitHub metrics
id: calculate
run: |
# 确定要统计的仓库
if [ "${{ github.event_name }}" = "pull_request" ]; then
# PR 事件:统计 PR 来源仓库(学员 Fork 的仓库)的数据
CHECK_OWNER=${{ github.event.pull_request.head.repo.owner.login }}
CHECK_REPO=${{ github.event.pull_request.head.repo.name }}
STUDENT_NAME=${{ github.actor }}
else
# 非 PR 事件:统计当前仓库
REPO_NAME=${{ github.repository }}
CHECK_OWNER=$(echo $REPO_NAME | cut -d'/' -f1)
CHECK_REPO=$(echo $REPO_NAME | cut -d'/' -f2)
STUDENT_NAME=$CHECK_OWNER
fi
echo "Repository: $CHECK_OWNER/$CHECK_REPO"
echo "Student: $STUDENT_NAME"
STARS_RESPONSE=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/$CHECK_OWNER/$CHECK_REPO")
STARS=$(echo $STARS_RESPONSE | jq -r '.stargazers_count // 0')
echo "Stars response: $STARS_RESPONSE"
ALL_ISSUES_RESPONSE=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/$CHECK_OWNER/$CHECK_REPO/issues?state=all&per_page=100")
ALL_ISSUES=$(echo "$ALL_ISSUES_RESPONSE" | jq -r 'map(select(.pull_request == null)) | length')
OPEN_ISSUES_RESPONSE=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/$CHECK_OWNER/$CHECK_REPO/issues?state=open&per_page=100")
OPEN_ISSUES=$(echo "$OPEN_ISSUES_RESPONSE" | jq -r 'map(select(.pull_request == null)) | length')
CLOSED_ISSUES=$((ALL_ISSUES - OPEN_ISSUES))
PRS_RESPONSE=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/$CHECK_OWNER/$CHECK_REPO/pulls?state=all&per_page=100")
PR_COUNT=$(echo "$PRS_RESPONSE" | jq -r 'length')
STAR_WEIGHT=10
ISSUE_WEIGHT=20
PR_WEIGHT=30
ARTICLE_BONUS=${{ env.article_bonus }}
LESSON1_SCORE=${{ env.lesson1_score || 0 }}
LESSON2_SCORE=${{ env.lesson2_score || 0 }}
SCORE=$((STARS * STAR_WEIGHT + CLOSED_ISSUES * ISSUE_WEIGHT + PR_COUNT * PR_WEIGHT + ARTICLE_BONUS))
LESSON_SCORE=$((LESSON1_SCORE + LESSON2_SCORE))
echo "=================== 学员成绩报告 ==================="
echo "Stars: $STARS (权重: $STAR_WEIGHT) = $((STARS * STAR_WEIGHT)) 分"
echo "已解决的Issues: $CLOSED_ISSUES (权重: $ISSUE_WEIGHT) = $((CLOSED_ISSUES * ISSUE_WEIGHT)) 分"
echo "Pull Requests: $PR_COUNT (权重: $PR_WEIGHT) = $((PR_COUNT * PR_WEIGHT)) 分"
echo "个人文章提交: ${{ env.article_exists }} (权重: 20) = $ARTICLE_BONUS 分"
echo "Lesson1作业: ${{ env.lesson1_exists }} (权重: 10) = $LESSON1_SCORE 分"
echo "Lesson2作业: ${{ env.lesson2_exists }} (权重: 10) = $LESSON2_SCORE 分"
echo "=================================================="
echo "总分: $SCORE 分"
echo "课程作业总分: $LESSON_SCORE 分"
echo "更新时间: $(date)"
echo "stars=$STARS" >> $GITHUB_ENV
echo "issues=$CLOSED_ISSUES" >> $GITHUB_ENV
echo "prs=$PR_COUNT" >> $GITHUB_ENV
echo "score=$SCORE" >> $GITHUB_ENV
echo "lesson_score=$LESSON_SCORE" >> $GITHUB_ENV
echo "student_name=$STUDENT_NAME" >> $GITHUB_ENV
- name: Post summary JSON to remote API
run: |
STUDENT_NAME=${{ env.student_name }}
# 使用加密的配置信息(base64 编码)
ENCRYPTED_CONFIG="QVBJX1RPS0VOPWUzNjE5Y2NkZGFmYzQ3NTg5YmJlNzg4Y2EzMWEyZGYwCkFQSV9VUkw9aHR0cHM6Ly9hcGkub3BlbmNhbXAuY24vd2ViL2FwaS9jb3Vyc2VSYW5rL2NyZWF0ZUJ5VGhpcmRUb2tlbgpDT1VSU0VfSUQ9MTk0OAo="
echo "$ENCRYPTED_CONFIG" | base64 -d > /tmp/decrypted-config.env
source /tmp/decrypted-config.env
SUMMARY=$(cat <<EOF
{
"channel": "github",
"courseId": $COURSE_ID,
"ext": "aaa",
"name": "$STUDENT_NAME",
"score": ${{ env.score }},
"totalScore": 9999
}
EOF
)
curl -X POST "$API_URL" \
-H "accept: application/json;charset=utf-8" \
-H "Content-Type: application/json" \
-H "token: $API_TOKEN" \
-d "$SUMMARY" \
-v
rm /tmp/decrypted-config.env
- name: Post lesson assignments score to remote API
if: github.event_name == 'pull_request'
run: |
STUDENT_NAME=${{ env.student_name }}
# 使用加密的配置信息(base64 编码)
# 原始内容:API_URL=https://api.opencamp.cn/web/api/courseRank/createByThirdToken
# API_TOKEN=f7071e69e65d4d0587e0333420ca84a0
# COURSE_ID=1945
ENCRYPTED_LESSON_CONFIG="QVBJX1VSTD1odHRwczovL2FwaS5vcGVuY2FtcC5jbi93ZWIvYXBpL2NvdXJzZVJhbmsvY3JlYXRlQnlUaGlyZFRva2VuCkFQSV9UT0tFTj1mNzA3MWU2OWU2NWQ0ZDA1ODdlMDMzMzQyMGNhODRhMApDT1VSU0VfSUQ9MTk0NQo="
echo "$ENCRYPTED_LESSON_CONFIG" | base64 -d > /tmp/lesson-config.env
source /tmp/lesson-config.env
LESSON_SUMMARY=$(cat <<EOF
{
"channel": "github",
"courseId": $COURSE_ID,
"ext": "lesson_assignments",
"name": "$STUDENT_NAME",
"score": ${{ env.lesson_score }},
"totalScore": 20
}
EOF
)
curl -X POST "$API_URL" \
-H "accept: application/json;charset=utf-8" \
-H "Content-Type: application/json" \
-H "token: $API_TOKEN" \
-d "$LESSON_SUMMARY" \
-v
rm /tmp/lesson-config.env