Skip to content

Commit 8a7a4a6

Browse files
committed
Automate generation of who.md file from list maintained by ASF
1 parent 4458cf7 commit 8a7a4a6

File tree

4 files changed

+326
-197
lines changed

4 files changed

+326
-197
lines changed

README.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ automation that can publish changes merged to 'main' branch being automatically
5151
published to the 'asf-site'. see the procedure below.
5252

5353

54-
## publishing procedure
54+
## Publishing procedure
5555

5656
- create a change
5757
- test your change according to [the previous chapter](#building-and-publishing)
@@ -75,3 +75,24 @@ git push
7575
- wait for asf-site to be updated and published to the main site
7676
- check again
7777
- go to sleep
78+
79+
80+
## Updating the who.md file
81+
82+
Every time new committers or PMC members are invited to CloudStack, the parent list maintained at: https://people.apache.org/committers-by-project.html#cloudstack is updated. This can be used to automate the generation of who.md file which is used at https://cloudstack.staged.apache.org/who/
83+
84+
To generate the who.md file, follow the given steps:
85+
86+
1. Install the necessary dependencies:
87+
88+
```
89+
pip install -r requirements.txt
90+
```
91+
92+
2. Run the `generate_who.py` script
93+
94+
```
95+
python3 source/generate_who.py
96+
```
97+
98+
NOTE: Currently, the PMC Chair's name needs to be manually updated in the script.

requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
requests>=2.25.0
2+
beautifulsoup4>=4.9.0
3+
GitPython>=3.1.0

source/generate_who.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import os
2+
import git
3+
import requests
4+
from bs4 import BeautifulSoup
5+
import locale
6+
7+
# Set locale to handle special characters properly (if necessary)
8+
locale.setlocale(locale.LC_COLLATE, 'en_US.UTF-8')
9+
10+
def fetch_cloudstack_members():
11+
url = "https://people.apache.org/committers-by-project.html#cloudstack"
12+
response = requests.get(url)
13+
response.encoding = 'utf-8'
14+
if response.status_code != 200:
15+
print("Failed to fetch the page")
16+
return None, None
17+
18+
soup = BeautifulSoup(response.text, "html.parser")
19+
20+
pmc_section = soup.find("h2", {"id": "cloudstack-pmc"})
21+
committers_section = soup.find("h2", {"id": "cloudstack"})
22+
23+
pmc_members = []
24+
committers = []
25+
26+
if pmc_section:
27+
pmc_table = pmc_section.find_next("table")
28+
if pmc_table:
29+
rows = pmc_table.find_all("tr")[1:] # Skip header row
30+
for row in rows:
31+
columns = row.find_all("td")
32+
if len(columns) >= 2:
33+
name = columns[1].text.strip()
34+
svn_id = columns[0].text.strip()
35+
pmc_members.append((name, svn_id))
36+
37+
if committers_section:
38+
committers_table = committers_section.find_next("table")
39+
if committers_table:
40+
rows = committers_table.find_all("tr")[1:] # Skip header row
41+
for row in rows:
42+
columns = row.find_all("td")
43+
if len(columns) >= 2:
44+
name = columns[1].text.strip()
45+
svn_id = columns[0].text.strip()
46+
committers.append((name, svn_id))
47+
48+
return pmc_members, committers
49+
50+
def get_repo_path():
51+
try:
52+
# Find the current working directory
53+
current_dir = os.getcwd()
54+
55+
# Check if it's a Git repository
56+
repo = git.Repo(current_dir)
57+
58+
# Get the absolute path of the repository
59+
repo_path = repo.git.rev_parse("--show-toplevel")
60+
return repo_path
61+
except git.exc.InvalidGitRepositoryError:
62+
print("Not a git repository.")
63+
return None
64+
65+
def generate_markdown(pmc_members, committers):
66+
# Sort the members alphabetically by their names
67+
pmc_members.sort(key=lambda x: locale.strxfrm(x[0].lower())) # Sort by name (case insensitive)
68+
committers.sort(key=lambda x: locale.strxfrm(x[0].lower())) # Sort by name (case insensitive)
69+
repo_path = get_repo_path()
70+
with open(repo_path + "/src/pages/who.md", "w", encoding="utf-8") as f:
71+
f.write("""---
72+
title: Apache CloudStack Project Membership
73+
---
74+
75+
# Apache CloudStack Project Members
76+
77+
PMC Information: https://projects.apache.org/committee.html?cloudstack
78+
79+
Board Minutes: https://whimsy.apache.org/board/minutes/CloudStack.html
80+
81+
""")
82+
83+
pmc_chair = "Daniel Augusto Veronezi Salvador (gutoveronezi)"
84+
f.write(f"**PMC Chair**: {pmc_chair}\n\n")
85+
86+
f.write("The following data is subject to change. The up-to-date information can be found on <a href=\"http://people.apache.org/committers-by-project.html#cloudstack-pmc\">the Apache Peoples site</a>:\n\n")
87+
88+
f.write("**PMC members (also in the [Committers](#committers) group)**:\n\n")
89+
for name, id in pmc_members:
90+
f.write(f"- {name} ({id})\n")
91+
92+
f.write("\n**<a name=\"committers\">Committers</a>**:\n\n")
93+
for name, id in committers:
94+
f.write(f"- {name} ({id})\n")
95+
print("who.md file has been generated successfully!")
96+
97+
def main():
98+
pmc_members, committers = fetch_cloudstack_members()
99+
if pmc_members and committers:
100+
generate_markdown(pmc_members, committers)
101+
102+
if __name__ == "__main__":
103+
main()

0 commit comments

Comments
 (0)