Skip to content

Commit 57126eb

Browse files
github-classroom[bot]kappsegla
authored andcommitted
Updated classroom.yml
0 parents  commit 57126eb

File tree

10 files changed

+351
-0
lines changed

10 files changed

+351
-0
lines changed

.github/dependabot.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
version: 2
2+
updates:
3+
# Maintain dependencies for GitHub Actions
4+
- package-ecosystem: "github-actions"
5+
directory: "/"
6+
schedule:
7+
interval: "weekly"
8+
groups:
9+
actions-deps:
10+
patterns:
11+
- "*"
12+
13+
# Maintain dependencies for Maven
14+
- package-ecosystem: "maven"
15+
directory: "/"
16+
schedule:
17+
interval: "weekly"
18+
groups:
19+
maven-deps:
20+
patterns:
21+
- "*"

.github/workflows/classroom.yml

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
name: Autograding Tests
2+
'on':
3+
- push
4+
- repository_dispatch
5+
6+
permissions:
7+
checks: write
8+
actions: read
9+
contents: read
10+
pull-requests: write
11+
12+
jobs:
13+
ai_feedback:
14+
name: AI-Powered Feedback
15+
runs-on: ubuntu-latest
16+
env:
17+
OPENROUTER_MODEL: ${{ vars.OPENROUTER_MODEL }}
18+
SYSTEM_PROMPT: ${{ vars.SYSTEM_PROMPT }}
19+
steps:
20+
- name: Checkout repository
21+
uses: actions/checkout@v5
22+
23+
- name: Read assignment instructions
24+
id: instructions
25+
run: |
26+
# Reads the content of the README.md file into an output variable.
27+
# The `EOF` marker is used to handle multi-line file content.
28+
echo "instructions=$(cat README.md | sed 's/\"/\\\"/g' | sed 's/$/\\n/' | tr -d '\n' | sed 's/\\n/\\\\n/g')" >> $GITHUB_OUTPUT
29+
30+
- name: Read source code
31+
id: source_code
32+
run: |
33+
{
34+
echo 'source_code<<EOF'
35+
find src/main/java -type f -name "*.java" | while read -r file; do
36+
echo "=== File: $file ==="
37+
cat "$file"
38+
echo
39+
done
40+
echo 'EOF'
41+
} >> "$GITHUB_OUTPUT"
42+
43+
- name: Read test code
44+
id: test_code
45+
run: |
46+
{
47+
echo 'test_code<<EOF'
48+
if [ -d "src/test/java" ]; then
49+
find src/test/java -type f -name "*.java" | while read -r file; do
50+
echo "=== File: $file ==="
51+
cat "$file"
52+
echo
53+
done
54+
else
55+
echo "No test code found."
56+
fi
57+
echo 'EOF'
58+
} >> "$GITHUB_OUTPUT"
59+
- name: Generate AI Feedback
60+
id: ai_feedback
61+
run: |
62+
# This step sends the collected data to the OpenRouter API.
63+
INSTRUCTIONS=$(jq -Rs . <<'EOF'
64+
${{ steps.instructions.outputs.instructions }}
65+
EOF
66+
)
67+
SOURCE_CODE=$(jq -Rs . <<'EOF'
68+
${{ steps.source_code.outputs.source_code }}
69+
EOF
70+
)
71+
TEST_CODE=$(jq -Rs . <<'EOF'
72+
${{ steps.test_code.outputs.test_code }}
73+
EOF
74+
)
75+
76+
if [ -z "$INSTRUCTIONS" ] || [ -z "$SOURCE_CODE" ] || [ -z "$TEST_CODE" ]; then
77+
echo "Error: One or more required variables are not set."
78+
exit 1
79+
fi
80+
81+
# Assigning to USER_CONTENT with variable expansion
82+
PAYLOAD="Please provide feedback on the following Java assignment.
83+
84+
--- Assignment Instructions ---
85+
${INSTRUCTIONS}
86+
87+
--- Source files ---
88+
${SOURCE_CODE}
89+
90+
--- Test files ---
91+
${TEST_CODE}"
92+
93+
JSON_CONTENT=$(jq -n \
94+
--argjson model "$OPENROUTER_MODEL" \
95+
--arg system_prompt "$SYSTEM_PROMPT" \
96+
--arg payload "$PAYLOAD" \
97+
'{
98+
models: $model,
99+
messages: [
100+
{role: "system", content: $system_prompt},
101+
{role: "user", content: $payload}
102+
]
103+
}')
104+
105+
echo "$JSON_CONTENT"
106+
107+
API_RESPONSE=$(echo "$JSON_CONTENT" | curl https://openrouter.ai/api/v1/chat/completions \
108+
-H "Authorization: Bearer ${{ secrets.OPENROUTER_API_KEY }}" \
109+
-H "Content-Type: application/json" \
110+
-d @-)
111+
112+
echo "$API_RESPONSE"
113+
114+
FEEDBACK_CONTENT=$(echo "$API_RESPONSE" | jq -r '.choices[0].message.content')
115+
echo "feedback<<EOF" >> $GITHUB_OUTPUT
116+
echo "$FEEDBACK_CONTENT" >> $GITHUB_OUTPUT
117+
echo "EOF" >> $GITHUB_OUTPUT
118+
- name: Post Feedback as PR Comment ✍️
119+
uses: actions/github-script@v7
120+
env:
121+
FEEDBACK_BODY: ${{ steps.ai_feedback.outputs.feedback }}
122+
with:
123+
github-token: ${{ secrets.GITHUB_TOKEN }}
124+
script: |
125+
const { owner, repo } = context.repo;
126+
const targetTitle = "Feedback";
127+
const signature = "🤖 AI Feedback";
128+
129+
const { data: pullRequests } = await github.rest.pulls.list({
130+
owner,
131+
repo,
132+
state: "open",
133+
per_page: 100
134+
});
135+
136+
const matchingPR = pullRequests.find(pr => pr.title.trim().toLowerCase() === targetTitle.toLowerCase());
137+
if (!matchingPR) {
138+
throw new Error(`No open pull request found with title '${targetTitle}'`);
139+
}
140+
141+
const prNumber = matchingPR.number;
142+
143+
const { data: comments } = await github.rest.issues.listComments({
144+
owner,
145+
repo,
146+
issue_number: prNumber,
147+
per_page: 100
148+
});
149+
150+
const existing = comments.find(c =>
151+
c.user?.login === "github-actions[bot]" &&
152+
c.body?.includes(signature)
153+
);
154+
155+
const timestamp = new Date().toISOString();
156+
const newEntry = `🕒 _Posted on ${timestamp}_\n\n${process.env.FEEDBACK_BODY}\n\n---\n`;
157+
158+
if (existing) {
159+
// Extract previous entries and wrap them in a collapsible block
160+
const previousContent = existing.body.replace(/^### 🤖 AI Feedback\s*/, '').trim();
161+
const collapsed = `<details><summary>Previous Feedback</summary>\n\n${previousContent}\n</details>`;
162+
163+
const updatedBody = `### ${signature}\n\n${newEntry}${collapsed}`;
164+
await github.rest.issues.updateComment({
165+
owner,
166+
repo,
167+
comment_id: existing.id,
168+
body: updatedBody
169+
});
170+
console.log(`🔄 Updated existing comment on PR #${prNumber}`);
171+
} else {
172+
const body = `### ${signature}\n\n${newEntry}`;
173+
await github.rest.issues.createComment({
174+
owner,
175+
repo,
176+
issue_number: prNumber,
177+
body
178+
});
179+
console.log(`🆕 Posted new comment on PR #${prNumber}`);
180+
}
181+
run-autograding-tests:
182+
name: Autograding
183+
runs-on: ubuntu-latest
184+
if: github.actor != 'github-classroom[bot]'
185+
steps:
186+
- name: Set up Java 25
187+
uses: actions/setup-java@v5
188+
with:
189+
distribution: 'temurin'
190+
java-version: '25'
191+
192+
- name: Checkout code
193+
uses: actions/checkout@v5
194+
195+
- name: Compilation Check
196+
id: compilation-check
197+
uses: classroom-resources/autograding-command-grader@v1
198+
with:
199+
test-name: Compilation Check
200+
command: mvn -ntp compile
201+
timeout: 10
202+
max-score: 1
203+
204+
- name: Basic Tests
205+
id: basic-tests
206+
uses: classroom-resources/autograding-command-grader@v1
207+
with:
208+
test-name: Basic Tests
209+
command: mvn -ntp test -Dtest=BasicTest
210+
timeout: 10
211+
max-score: 1
212+
213+
- name: Edge Case Tests
214+
id: edge-case-tests
215+
uses: classroom-resources/autograding-command-grader@v1
216+
with:
217+
test-name: Edge Case Tests
218+
command: mvn -ntp test -Dtest=EdgeCaseTest
219+
timeout: 10
220+
max-score: 1
221+
222+
- name: Autograding Reporter
223+
uses: classroom-resources/autograding-grading-reporter@v1
224+
env:
225+
COMPILATION-CHECK_RESULTS: "${{steps.compilation-check.outputs.result}}"
226+
BASIC-TESTS_RESULTS: "${{steps.basic-tests.outputs.result}}"
227+
EDGE-CASE-TESTS_RESULTS: "${{steps.edge-case-tests.outputs.result}}"
228+
with:
229+
runners: compilation-check,basic-tests,edge-case-tests

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
target/
2+
/.idea/

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# 🚀 Requirements
2+
3+
Add requirements here

pom.xml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>org.example</groupId>
8+
<artifactId>Java-Core</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
11+
<properties>
12+
<maven.compiler.release>25</maven.compiler.release>
13+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
14+
<junit.jupiter.version>5.13.4</junit.jupiter.version>
15+
<assertj.core.version>3.27.5</assertj.core.version>
16+
<mockito.version>5.20.0</mockito.version>
17+
</properties>
18+
<dependencies>
19+
<dependency>
20+
<groupId>org.junit.jupiter</groupId>
21+
<artifactId>junit-jupiter</artifactId>
22+
<version>${junit.jupiter.version}</version>
23+
<scope>test</scope>
24+
</dependency>
25+
<dependency>
26+
<groupId>org.assertj</groupId>
27+
<artifactId>assertj-core</artifactId>
28+
<version>${assertj.core.version}</version>
29+
<scope>test</scope>
30+
</dependency>
31+
<dependency>
32+
<groupId>org.mockito</groupId>
33+
<artifactId>mockito-junit-jupiter</artifactId>
34+
<version>${mockito.version}</version>
35+
<scope>test</scope>
36+
</dependency>
37+
</dependencies>
38+
<build>
39+
<plugins>
40+
<plugin>
41+
<groupId>org.jacoco</groupId>
42+
<artifactId>jacoco-maven-plugin</artifactId>
43+
<version>0.8.13</version>
44+
<configuration>
45+
<skip>true</skip>
46+
</configuration>
47+
<executions>
48+
<execution>
49+
<id>default-prepare-agent</id>
50+
<goals>
51+
<goal>prepare-agent</goal>
52+
</goals>
53+
</execution>
54+
<execution>
55+
<id>default-report</id>
56+
<phase>prepare-package</phase>
57+
<goals>
58+
<goal>report</goal>
59+
</goals>
60+
</execution>
61+
</executions>
62+
</plugin>
63+
</plugins>
64+
</build>
65+
</project>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.example;
2+
3+
public class Main {
4+
public static void main(String[] args) {
5+
6+
}
7+
}

src/main/resources/.gitkeep

Whitespace-only changes.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.example;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.assertj.core.api.Assertions.assertThat;
6+
7+
public class BasicTest {
8+
@Test
9+
void shouldAlwaysPass() {
10+
assertThat(1 + 1).isEqualTo(2);
11+
}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.example;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.assertj.core.api.Assertions.assertThat;
6+
7+
public class EdgeCaseTest {
8+
@Test
9+
void shouldAlwaysFail() {
10+
assertThat("actual").isEqualTo("expected");
11+
}
12+
}

src/test/resources/.gitkeep

Whitespace-only changes.

0 commit comments

Comments
 (0)