Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/clone-repos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ jobs:
import json
import os
import subprocess
import requests

# Check if submissions.json exists
if not os.path.exists("submissions.json"):
Expand All @@ -59,6 +60,7 @@ jobs:
os.makedirs("Submissions", exist_ok=True)

new_repos_cloned = False
failed_clones = []

for submission in submissions:
name = submission.get("name", "unknown")
Expand All @@ -69,6 +71,30 @@ jobs:
print(f"No repository URL found for {name}, skipping...")
continue

# Check if repo is public and not too large
try:
parts = repo_url.rstrip("/").split("/")
owner, repo = parts[-2], parts[-1].replace('.git','')
api_url = f"https://api.github.com/repos/{owner}/{repo}"
resp = requests.get(api_url)
if resp.status_code != 200:
print(f"Repository {repo_url} is not accessible (status {resp.status_code}), skipping...")
failed_clones.append(repo_url)
continue
repo_info = resp.json()
if repo_info.get("private"):
print(f"Repository {repo_url} is private, skipping...")
failed_clones.append(repo_url)
continue
if repo_info.get("size", 0) > 100000: # ~100MB
print(f"Repository {repo_url} is too large (>100MB), skipping...")
failed_clones.append(repo_url)
continue
except Exception as e:
print(f"Error checking repo {repo_url}: {e}")
failed_clones.append(repo_url)
continue

clone_path = os.path.join("Submissions", project_name)

if os.path.exists(clone_path):
Expand All @@ -88,12 +114,25 @@ jobs:
print(f"Successfully cloned {repo_url}")
except subprocess.CalledProcessError as e:
print(f"Failed to clone {repo_url}: {e}")
failed_clones.append(repo_url)

if new_repos_cloned:
with open(os.environ["GITHUB_ENV"], "a") as env_file:
env_file.write("NEW_CLONES=true\n")
if failed_clones:
with open("clone_failures.txt", "w") as f:
for url in failed_clones:
f.write(url + "\n")
'

- name: Notify maintainers of failed clones
if: always()
run: |
if [ -f clone_failures.txt ]; then
echo "Some repositories failed to clone. Notifying maintainers."
gh issue create --title "Repository Clone Failures" --body "The following repositories could not be cloned during the last run:\n\n$(cat clone_failures.txt)" || true
fi

- name: Commit and Push Cloned Repositories
if: env.NEW_CLONES == 'true'
run: |
Expand Down
22 changes: 21 additions & 1 deletion .github/workflows/issue-to-submission.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,30 @@ jobs:
return;
}

// Check for required headings to ensure template format
const requiredHeadings = [
'### Name',
'### Project Name',
'### GitHub Repository URL',
'### Project Description'
];
for (const heading of requiredHeadings) {
if (!body.includes(heading)) {
core.setFailed('Issue template format has changed or is incomplete.');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: `❌ **Error:** The issue template format is incorrect or missing required headings. Please use the official submission template.`
});
return;
}
}

const nameMatch = body.match(/### Name\s*\n\s*([^\n]+)/);
const projectMatch = body.match(/### Project Name\s*\n\s*([^\n]+)/);
const repoMatch = body.match(/### GitHub Repository URL\s*\n\s*([^\n]+)/);
const descMatch = body.match(/### Project Description\s*\n\s*([\s\S]*?)(?=###|$)/);
const descMatch = body.match(/### Project Description\s*\n*([\s\S]*?)(?=###|$)/);

if (!nameMatch || !projectMatch || !repoMatch || !descMatch) {
core.setFailed('Could not extract all required information from issue');
Expand Down
20 changes: 11 additions & 9 deletions .github/workflows/merge-pr-on-issue-close.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,21 +113,23 @@ jobs:
git show origin/main:submissions.json > main_submissions.json || touch main_submissions.json
git show "$PR_BRANCH":submissions.json > pr_submissions.json || touch pr_submissions.json

# Merge JSON contents (ensuring unique submissions by repository_url)
jq -s 'add | group_by(.repository_url) | map(if .[0].repository_url == "" then .[0] else .[] end)' main_submissions.json pr_submissions.json > submissions.json
# Merge JSON contents (ensuring unique submissions by repository_url and removing empty/invalid entries)
jq -s 'add | map(select(.repository_url and .name and .project_name and .description and (.repository_url|test("^https?://github\\.com/[\\w-]+/[\\w-]+(?:\\.git)?$"))) | unique_by(.repository_url)' main_submissions.json pr_submissions.json > submissions.json

# Stage the resolved file
git add submissions.json
if git rebase --continue; then
echo "✅ Merge conflicts resolved, rebase successful."
echo "✅ Merge conflicts resolved, rebase successful."
elif git status --porcelain | grep submissions.json; then
git add submissions.json
git commit -m "$PR_TITLE"
git rebase --continue
git add submissions.json
git commit -m "$PR_TITLE"
git rebase --continue
else
echo "⚠️ Rebase still failing. Aborting..."
git rebase --abort
exit 1
echo "⚠️ Rebase still failing. Aborting..."
git rebase --abort
# Notify maintainers of failure
gh issue comment "$ISSUE_NUMBER" --body "❌ Merge conflict in submissions.json could not be resolved automatically. Manual intervention required."
exit 1
fi
fi

Expand Down
15 changes: 12 additions & 3 deletions .github/workflows/submission-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ jobs:
- name: Check if PR is Late
id: deadline-check
run: |
DEADLINE="2025-02-02T13:30:00Z"
# Read deadline from config.yml
DEADLINE=$(python3 -c 'import yaml; print(yaml.safe_load(open("config.yml"))["deadline"])' 2>/dev/null || python3 -c 'import sys, yaml; print(yaml.safe_load(sys.stdin)["deadline"])' < config.yml)
CURRENT_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

if [[ "$CURRENT_TIME" > "$DEADLINE" ]]; then
Expand All @@ -68,13 +69,21 @@ jobs:
python -c '
import json
import sys
import re
try:
with open("submissions.json", "r") as f:
submissions = json.load(f)
required_keys = ["name", "project_name", "repository_url", "description"]
url_pattern = r"^https?://github\\.com/[\\w-]+/[\\w-]+(?:\\.git)?$"
for submission in submissions:
if not all(k in submission for k in required_keys):
print("❌ Invalid submission format")
# Check all required keys are present and non-empty
for k in required_keys:
if k not in submission or not str(submission[k]).strip():
print(f"❌ Invalid submission: missing or empty field '{k}'")
sys.exit(1)
# Check repository_url format
if not re.match(url_pattern, submission["repository_url"]):
print(f"❌ Invalid repository_url format: {submission['repository_url']}")
sys.exit(1)
print("✅ Valid submissions.json")
except Exception as e:
Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,18 @@ This repository provides an **automated workflow** to manage **hackathon project

---

## ⚠️ Important Notes

- **Deadline:** The current submission deadline is **June 30, 2025**. Update the deadline in `config.yml` at the root of the repository to change it. The workflow reads the deadline from this YAML config file.
- **Late Submissions:** PRs submitted after the deadline will be marked with `[LATE]` in the title and the `late-submission` label. Reviewers can still approve and merge late submissions, but they will be clearly marked.
- **Template Format:** The workflows require the issue template format to remain unchanged. If you modify the template, update the extraction logic in the workflow accordingly.
- **Repository Cloning:** Only public repositories under 100MB will be cloned. Private or oversized repositories will be skipped, and maintainers will be notified of any failures.

---

## 🔧 Configuration
- **Add Labels:** Add labels `project-submission` and `late-submission`
- **Deadline Date:** Update the `DEADLINE` in `.github/workflows/submission-validation.yml`
- **Add Labels:** Add labels `project-submission` and `late-submission` to your repository.
- **Deadline Date:** Update the `deadline` in `config.yml` at the root of the repository.
- **Required Fields in `submissions.json`**:
```json
[
Expand Down
1 change: 1 addition & 0 deletions config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
deadline: "2025-06-30T23:59:59Z"
Loading