Skip to content

Commit e083ef8

Browse files
Add auto-save submission workflow and contributors tracking
1 parent e03c58d commit e083ef8

2 files changed

Lines changed: 165 additions & 0 deletions

File tree

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
name: Save Submission on Issue Close
2+
3+
on:
4+
issues:
5+
types: [closed]
6+
7+
permissions:
8+
contents: write
9+
issues: write
10+
11+
jobs:
12+
save-submission:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v4
17+
18+
- name: Extract and save submission
19+
uses: actions/github-script@v7
20+
with:
21+
script: |
22+
const fs = require('fs');
23+
const issue = context.payload.issue;
24+
25+
// Get all comments on the issue
26+
const comments = await github.rest.issues.listComments({
27+
owner: context.repo.owner,
28+
repo: context.repo.repo,
29+
issue_number: issue.number
30+
});
31+
32+
// Find submission comment (look for "## Submission" or last substantial comment)
33+
let submissionContent = null;
34+
let submitter = issue.user.login;
35+
36+
for (const comment of comments.data.reverse()) {
37+
if (comment.body.toLowerCase().includes('submission') ||
38+
comment.body.toLowerCase().includes('deliverable') ||
39+
comment.body.length > 200) {
40+
submissionContent = comment.body;
41+
submitter = comment.user.login;
42+
break;
43+
}
44+
}
45+
46+
// If no comment found, use issue body
47+
if (!submissionContent) {
48+
submissionContent = issue.body || 'No submission content found.';
49+
}
50+
51+
// Create slug from issue title
52+
const slug = issue.title
53+
.toLowerCase()
54+
.replace(/[^a-z0-9]+/g, '-')
55+
.replace(/^-|-$/g, '')
56+
.substring(0, 50);
57+
58+
// Create submission file content
59+
const date = new Date().toISOString().split('T')[0];
60+
const fileContent = `# ${issue.title}
61+
62+
**Issue:** #${issue.number}
63+
**Submitted by:** @${submitter}
64+
**Closed on:** ${date}
65+
**Labels:** ${issue.labels.map(l => l.name).join(', ') || 'None'}
66+
67+
---
68+
69+
${submissionContent}
70+
71+
---
72+
73+
*Auto-generated from [Issue #${issue.number}](${issue.html_url})*
74+
`;
75+
76+
// Ensure submissions directory exists
77+
const submissionsDir = 'submissions';
78+
if (!fs.existsSync(submissionsDir)) {
79+
fs.mkdirSync(submissionsDir);
80+
}
81+
82+
// Write submission file
83+
const filename = `${submissionsDir}/issue-${issue.number}-${slug}.md`;
84+
fs.writeFileSync(filename, fileContent);
85+
86+
// Update contributors file
87+
const contributorsFile = 'CONTRIBUTORS.md';
88+
let contributorsContent = '';
89+
90+
if (fs.existsSync(contributorsFile)) {
91+
contributorsContent = fs.readFileSync(contributorsFile, 'utf8');
92+
} else {
93+
contributorsContent = `# Contributors
94+
95+
This file tracks all contributions to JustLab AI tasks.
96+
97+
| Contributor | Tasks Completed | Last Contribution |
98+
|-------------|-----------------|-------------------|
99+
`;
100+
}
101+
102+
// Parse existing contributors
103+
const lines = contributorsContent.split('\n');
104+
const tableStart = lines.findIndex(l => l.startsWith('|----------'));
105+
let contributors = {};
106+
107+
if (tableStart !== -1) {
108+
for (let i = tableStart + 1; i < lines.length; i++) {
109+
const match = lines[i].match(/\|\s*@(\w+)\s*\|\s*(\d+)\s*\|/);
110+
if (match) {
111+
contributors[match[1]] = parseInt(match[2]);
112+
}
113+
}
114+
}
115+
116+
// Update contributor count
117+
contributors[submitter] = (contributors[submitter] || 0) + 1;
118+
119+
// Rebuild contributors table
120+
const sortedContributors = Object.entries(contributors)
121+
.sort((a, b) => b[1] - a[1]);
122+
123+
let newTable = `# Contributors
124+
125+
This file tracks all contributions to JustLab AI tasks.
126+
127+
| Contributor | Tasks Completed | Last Contribution |
128+
|-------------|-----------------|-------------------|
129+
`;
130+
for (const [user, count] of sortedContributors) {
131+
const isCurrentUser = user === submitter ? date : '-';
132+
newTable += `| @${user} | ${count} | ${isCurrentUser} |\n`;
133+
}
134+
135+
fs.writeFileSync(contributorsFile, newTable);
136+
137+
// Set outputs for commit
138+
core.setOutput('filename', filename);
139+
core.setOutput('submitter', submitter);
140+
141+
- name: Commit and push changes
142+
run: |
143+
git config --local user.email "github-actions[bot]@users.noreply.github.com"
144+
git config --local user.name "github-actions[bot]"
145+
git add submissions/ CONTRIBUTORS.md
146+
git commit -m "Add submission for issue #${{ github.event.issue.number }} by @${{ github.event.issue.user.login }}" || exit 0
147+
git push
148+
149+
- name: Comment on issue
150+
uses: actions/github-script@v7
151+
with:
152+
script: |
153+
await github.rest.issues.createComment({
154+
owner: context.repo.owner,
155+
repo: context.repo.repo,
156+
issue_number: context.payload.issue.number,
157+
body: `Submission saved to \`submissions/issue-${context.payload.issue.number}-*.md\`\n\nThank you for your contribution, @${context.payload.issue.user.login}!`
158+
});

CONTRIBUTORS.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Contributors
2+
3+
This file tracks all contributions to JustLab AI tasks.
4+
5+
| Contributor | Tasks Completed | Last Contribution |
6+
|-------------|-----------------|-------------------|
7+
| @YinuoYang327 | 1 | 2025-12-03 |

0 commit comments

Comments
 (0)