Skip to content

Commit fb1fcce

Browse files
Auto archive sections (#583)
Co-authored-by: Joe Clay <[email protected]>
1 parent eba921b commit fb1fcce

File tree

2 files changed

+194
-0
lines changed

2 files changed

+194
-0
lines changed

.github/workflows/check-archives.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Check Archive Status
2+
3+
on:
4+
schedule:
5+
- cron: "0 0 * * THU" # Run weekly on Thursdays
6+
workflow_dispatch: # Allow manual trigger
7+
8+
jobs:
9+
check-archives:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v3
13+
with:
14+
fetch-depth: 0 # Fetch all history for all branches and tags
15+
16+
# Check if there's already an open PR
17+
- name: Check for existing PR
18+
id: check_pr
19+
env:
20+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
21+
run: |
22+
pr_count=$(gh pr list --json number --search "is:open is:pr author:app/github-actions head:update-archive-status" --jq length)
23+
echo "has_open_pr=$([[ "$pr_count" -gt 0 ]] && echo 'true' || echo 'false')" >> "$GITHUB_OUTPUT"
24+
25+
- name: Set up Python
26+
if: steps.check_pr.outputs.has_open_pr != 'true'
27+
uses: actions/setup-python@v4
28+
with:
29+
python-version: "3.x"
30+
31+
- name: Install dependencies
32+
if: steps.check_pr.outputs.has_open_pr != 'true'
33+
run: |
34+
python -m pip install --upgrade pip
35+
pip install requests pytoml
36+
gh --version || true
37+
38+
- name: Check archive status
39+
if: steps.check_pr.outputs.has_open_pr != 'true'
40+
env:
41+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42+
run: python .github/workflows/check_archives.py
43+
44+
- name: Create Pull Request
45+
if: steps.check_pr.outputs.has_open_pr != 'true'
46+
uses: peter-evans/create-pull-request@v5
47+
with:
48+
commit-message: Update repository archive status
49+
title: Update repository archive status
50+
body: |
51+
This PR updates the archive status of GitHub repositories based on their current state.
52+
53+
This is an automated update triggered by the weekly archive status check.
54+
branch: update-archive-status
55+
base: master # Specify the base branch
56+
delete-branch: true

.github/workflows/check_archives.py

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import os
2+
import requests
3+
import pytoml
4+
import json
5+
from pathlib import Path
6+
7+
8+
def load_toml(file_path):
9+
with open(file_path, "r", encoding="utf-8") as f:
10+
return pytoml.load(f)
11+
12+
13+
def save_toml(file_path, data):
14+
with open(file_path, "w", encoding="utf-8") as f:
15+
pytoml.dump(data, f)
16+
17+
18+
def check_github_archive_status(repo_full_name, token):
19+
headers = {
20+
"Authorization": f"token {token}",
21+
"Accept": "application/vnd.github.v3+json",
22+
}
23+
url = f"https://api.github.com/repos/{repo_full_name}"
24+
response = requests.get(url, headers=headers)
25+
26+
if response.status_code == 200:
27+
return response.json().get("archived", False)
28+
return None
29+
30+
31+
def get_crates_io_repository(crate_name):
32+
headers = {"User-Agent": "arewegameyet ([email protected])"}
33+
url = f"https://crates.io/api/v1/crates/{crate_name}"
34+
try:
35+
response = requests.get(url, headers=headers)
36+
response.raise_for_status() # Raise an error for bad status codes
37+
38+
data = response.json()
39+
if not data or "crate" not in data:
40+
print(f"Warning: Invalid response from crates.io for {crate_name}")
41+
return None
42+
43+
repo_url = data["crate"].get("repository")
44+
if not repo_url:
45+
print(f"Warning: No repository URL found for crate {crate_name}")
46+
return None
47+
48+
if "github.com" not in repo_url:
49+
print(f"Info: Non-GitHub repository for crate {crate_name}: {repo_url}")
50+
return None
51+
52+
parts = repo_url.split("github.com/")
53+
if len(parts) != 2:
54+
print(f"Warning: Malformed GitHub URL for crate {crate_name}: {repo_url}")
55+
return None
56+
57+
return parts[1].rstrip("/")
58+
except requests.exceptions.RequestException as e:
59+
print(f"Error fetching crate {crate_name} from crates.io: {e}")
60+
return None
61+
except (KeyError, ValueError, AttributeError) as e:
62+
print(f"Error parsing response for crate {crate_name}: {e}")
63+
return None
64+
65+
66+
def extract_github_repo(item):
67+
if not item or not isinstance(item, dict):
68+
print(f"Warning: Invalid item format: {item}")
69+
return None
70+
71+
if item.get("source") == "github":
72+
return item.get("name")
73+
elif item.get("source") == "crates":
74+
name = item.get("name")
75+
if not name:
76+
print(f"Warning: No name found for crates.io item: {item}")
77+
return None
78+
return get_crates_io_repository(name)
79+
80+
repo_url = item.get("repository_url", "")
81+
if not repo_url:
82+
return None
83+
84+
if "github.com" in repo_url:
85+
parts = repo_url.split("github.com/")
86+
if len(parts) == 2:
87+
return parts[1].rstrip("/")
88+
89+
return None
90+
91+
92+
def main():
93+
token = os.environ.get("GITHUB_TOKEN")
94+
if not token:
95+
print("No GitHub token found")
96+
return
97+
98+
content_dir = Path("content")
99+
changes_made = False
100+
101+
for data_file in content_dir.rglob("data.toml"):
102+
# Skip the contributors data file
103+
if "contributors/data.toml" in str(data_file):
104+
print(f"Skipping contributors file: {data_file}")
105+
continue
106+
107+
print(f"Processing {data_file}")
108+
data = load_toml(data_file)
109+
file_changes_made = False
110+
111+
for item in data.get("items", []):
112+
# Skip if already archived
113+
if item.get("archived", False):
114+
print(f"Skipping already archived item: {item.get('name')}")
115+
continue
116+
117+
repo = extract_github_repo(item)
118+
if not repo:
119+
continue
120+
121+
print(f"Checking {repo}")
122+
is_archived = check_github_archive_status(repo, token)
123+
124+
if is_archived is True: # Only update if GitHub says it's archived
125+
item["archived"] = True
126+
file_changes_made = True
127+
changes_made = True
128+
print(f"Marked {repo} as archived")
129+
130+
if file_changes_made:
131+
save_toml(data_file, data)
132+
133+
if not changes_made:
134+
print("No changes were needed to archive status")
135+
136+
137+
if __name__ == "__main__":
138+
main()

0 commit comments

Comments
 (0)