Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

maintainers.html: Add list of maintainers #141

Merged
merged 11 commits into from
Dec 9, 2024
2 changes: 1 addition & 1 deletion .github/workflows/deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
- name: Update RIOT data
run: make update_riot_data
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.RIOT_CI_ACCESS_TOKEN }}

# Use GitHub Actions' cache to shorten build times and decrease load on servers
- uses: actions/cache@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/receive_pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Update RIOT data
run: make update_riot_data
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.RIOT_CI_ACCESS_TOKEN }}

# Use GitHub Actions' cache to shorten build times and decrease load on servers
- uses: actions/cache@v4
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ RIOT_DATA_FILES += $(DATA_DIR)/riot_contributors.yml
RIOT_DATA_FILES += $(DATA_DIR)/riot_drivers.yml
RIOT_DATA_FILES += $(DATA_DIR)/riot_drivers_cats.yml
RIOT_DATA_FILES += $(DATA_DIR)/riot_cpus.yml
RIOT_DATA_FILES += $(DATA_DIR)/riot_maintainers.yml

WATCH ?= 0

Expand All @@ -40,6 +41,8 @@ ifeq ($(RIOTBASE),$(_DEFAULT_RIOTBASE))
@git -C $(RIOTBASE) pull
endif

$(DATA_DIR)/riot_maintainers.yml: $(RIOTBASE)/CODEOWNERS

$(RIOT_DATA_FILES):
@$(RIOT_FETCH_DATA_CMD)

Expand Down
1 change: 1 addition & 0 deletions _includes/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<li class="dropdown"><a href="{% link community.html %}"><span>Community</span> <i class="bi bi-chevron-down"></i></a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a href="{% link community.html %}">Overview</a></li>
<li><a href="{% link maintainers.html %}">Maintainers</a></li>
<li><a href="https://forum.riot-os.org" target="_blank">Forum <i class="bi bi-box-arrow-up-right align-text-bottom"></i></a></li>
<li><a href="https://github.com/topics/riot-os" target="_blank">GitHub <i class="bi bi-box-arrow-up-right align-text-bottom"></i></a></li>
<li><a class="scrollto" href="{% link community.html %}#socialmedia">Social Media</a></li>
Expand Down
2 changes: 2 additions & 0 deletions _layouts/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
<script src="{{ "assets/vendor/php-email-form/validate.js" | relative_url }}"></script>
<script src="{{ "assets/vendor/swiper/swiper-bundle.min.js" | relative_url }}"></script>
<script src="{{ "assets/vendor/jquery/jquery_2_1_1.min.js" | relative_url }}"></script>
<script src="{{ "assets/vendor/masonry/masonry.pkgd.min.js" | relative_url }}"></script>


<!-- Template Main JS File -->
<script src="{{ "assets/js/main.js" | relative_url }}"></script>
Expand Down
8 changes: 8 additions & 0 deletions _sass/pages/about.scss
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,11 @@
margin: 5px 5px 5px 5px;
}
}

#maintainers {
.maintainers-img {
width: 22px;
border-radius: 50%;
margin: 1px;
}
}
69 changes: 69 additions & 0 deletions _tools/default_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,75 @@
"avatar_url": "https://avatars.githubusercontent.com/u/5160052?v=4",
},
]
DEFAULT_MAINTAINERS = [
{
"login": "miri64",
"avatar_url": "https://avatars.githubusercontent.com/u/675644?v=4",
"name": "Martine Lenders",
"html_url": "https://github.com/miri64",
"admin": True,
"owner": False,
"areas": [
"sys/net",
"tests/*/tests/*.py",
],
},
{
"login": "aabadie",
"avatar_url": "https://avatars.githubusercontent.com/u/1375137?v=4",
"name": "Alexandre Abadie",
"html_url": "https://github.com/aabadie",
"admin": False,
"owner": False,
"areas": [
"pkg/semtech-loramac/",
"doc/",
],
},
{
"login": "OlegHahm",
"name": "Oleg Hahm",
"avatar_url": "https://avatars.githubusercontent.com/u/1590423?v=4",
"html_url": "https://github.com/OlegHahm",
"admin": False,
"owner": True,
"areas": [],
},
{
"login": "kaspar030",
"avatar_url": "https://avatars.githubusercontent.com/u/4679640?v=4",
"name": "Kaspar Schleiser",
"html_url": "https://github.com/kaspar030",
"admin": False,
"owner": True,
"areas": [
"sys/include/ztimer.h",
"pm.c",
],
},
{
"login": "benpicco",
"avatar_url": "https://avatars.githubusercontent.com/u/1301112?v=4",
"html_url": "https://github.com/benpicco",
"name": "",
"admin": True,
"owner": False,
"areas": [
"drivers/at86rf215/",
],
},
{
"login": "biboc",
"avatar_url": "https://avatars.githubusercontent.com/u/4921425?v=4",
"html_url": "https://github.com/biboc",
"name": "biboc",
"admin": False,
"owner": False,
"areas": [
"cpu/samd21/",
],
},
]
DEFAULT_STATS = {
"boards": len(DEFAULT_BOARDS),
"cpus": len(DEFAULT_BOARDS),
Expand Down
109 changes: 107 additions & 2 deletions _tools/fetch_riot_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

from default_data import (
DEFAULT_BOARDS, DEFAULT_CPUS, DEFAULT_DRIVERS,
DEFAULT_DRIVER_CATEGORIES, DEFAULT_CONTRIBUTORS, DEFAULT_STATS
DEFAULT_DRIVER_CATEGORIES, DEFAULT_CONTRIBUTORS, DEFAULT_STATS,
DEFAULT_MAINTAINERS,
)

DATA_DIR = os.getenv("DATA_DIR", os.path.join(os.path.abspath(__file__)))
Expand Down Expand Up @@ -57,13 +58,23 @@
commits: ${commits}
"""

MAINTAINERS_TEMPLATE = """- login: ${login}
avatar_url: ${avatar_url}
html_url: https://github.com/${login}
name: ${name}
admin: ${admin}
owner: ${owner}
areas: ${areas}
"""

TEMPLATES = {
"boards": BOARDS_TEMPLATE,
"cpus": CPU_TEMPLATE,
"drivers": DRIVERS_TEMPLATE,
"drivers_cats": DRIVER_CATEGORIES_TEMPLATE,
"contributors": CONTRIBUTORS_TEMPLATE,
"stats": STATS_TEMPLATE,
"maintainers": MAINTAINERS_TEMPLATE,
}


Expand Down Expand Up @@ -117,6 +128,51 @@ def fetch_contributors_data():
]


def fetch_maintainer_data():
if requests is None:
print(
"Warning: 'requests' package is missing, default contributors "
"will be returned (only 10 contributors).\nYou can install "
"'requests' using 'make install_python_requirements'."
)
return DEFAULT_MAINTAINERS
if not os.getenv("GITHUB_TOKEN"):
print(
"Warning: no GitHub token provided via GITHUB_TOKEN environment "
"variable, default maintainers will be returned (only 6 "
"maintainers).\nYou need a GitHub personal access token with "
"admin:org > read:org scope."
)
return DEFAULT_MAINTAINERS
maintainers = get_team_members("maintainers")
admins = get_team_members("admin")
owners = get_team_members("owners")
maintainers = maintainers.union(admins)
maintainers = maintainers.union(owners)
maintainer_areas = get_maintainer_codeowner_patterns(maintainers)
res = []
for maintainer in maintainer_areas:
github_profile = get_github_user(maintainer)
if "login" not in github_profile or github_profile["login"] != maintainer:
print(
"Warning: error on fetching GitHub profile. Make sure "
"the GITHUB_TOKEN has appropriate rights"
)
return DEFAULT_MAINTAINERS
res.append(
{
"login": maintainer,
"name": github_profile["name"],
"avatar_url": github_profile["avatar_url"],
"html_url": github_profile["html_url"],
"admin": maintainer in admins,
"owner": maintainer in owners,
"areas": list(sorted(maintainer_areas[maintainer])),
}
)
return res


def search_data(file_paths, regexp, parent_regexp=None, multi=False):
"""Search doxygen data in a list of files/dirs using regexps."""
results = []
Expand Down Expand Up @@ -273,6 +329,54 @@ def fetch_stats_data():
}


def get_team_members(team):
token = os.getenv("GITHUB_TOKEN")
assert token is not None
members = requests.get(
f"https://api.github.com/orgs/RIOT-OS/teams/{team}/members",
headers={
"Accept": "application/vnd.github+json",
"Authorization": f"Bearer {token}",
"X-GitHub-Api-Version": "2022-11-28",
},
)
try:
return set(m["login"] for m in members.json())
except Exception as exc:
print(f"Error fetching team {team}: {exc}", file=sys.stderr)
raise


def get_github_user(username):
token = os.getenv("GITHUB_TOKEN")
assert token is not None
user = requests.get(
f"https://api.github.com/users/{username}",
headers={
"Accept": "application/vnd.github+json",
"Authorization": f"Bearer {token}",
"X-GitHub-Api-Version": "2022-11-28",
},
)
return user.json()


def get_maintainer_codeowner_patterns(maintainers):
maintainer_patterns = {m: set() for m in maintainers}

with open(os.path.join(RIOTBASE, "CODEOWNERS")) as codeowners_file:
for line in codeowners_file:
if re.search(r"^\s*#", line) or re.match(r"^\s*$", line):
# skip comments and empty lines
continue
pattern, *owners = re.split(r"\s+", line.strip())
for owner in owners:
owner = owner.lstrip("@")
if owner in maintainer_patterns:
maintainer_patterns[owner].add(pattern.lstrip("/"))
return maintainer_patterns


def main():
"""Main function."""
if not os.path.exists(RIOTBASE):
Expand All @@ -290,11 +394,12 @@ def main():
drivers = fetch_drivers_data()
driver_categories = fetch_driver_categories_data()
contributors = fetch_contributors_data()
maintainers = fetch_maintainer_data()
stats = fetch_stats_data()
for name, data in (
("boards", boards), ("cpus", cpus), ("drivers", drivers),
("drivers_cats", driver_categories), ("contributors", contributors),
("stats", [stats])
("stats", [stats]), ("maintainers", maintainers)
):
render_data_to_file(name, data)
if os.path.exists(RIOTBASE):
Expand Down
9 changes: 9 additions & 0 deletions assets/vendor/masonry/masonry.pkgd.min.js

Large diffs are not rendered by default.

67 changes: 67 additions & 0 deletions maintainers.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
layout: simple-page
title: RIOT Maintainers
subtitle: Our maintainers help RIOT to grow and improve.
---
<main>
<!-- ======= Maintainers Section ======= -->
<section id="maintainers">
<div class="container">
<p>
The RIOT community is supported by the following maintainers.
If a maintainer has expertise in certain parts of the
<a href="https://github.com/RIOT-OS/RIOT" target="_blank">RIOT codebase</a> and has declared
this within
<a href="https://github.com/RIOT-OS/RIOT/blob/master/CODEOWNERS" target="_blank">CODEOWNERS</a>,
this is explicitly noted.
</p>

<p id="maintainer-list">
miri64 marked this conversation as resolved.
Show resolved Hide resolved
<div class="row row-cols-1 row-cols-lg-3 row-cols-md-2 row-cols g-4"
data-masonry='{"percentPosition": true }'>
{% assign maintainer_by_login = site.data.riot_maintainers | sort_natural: "login" %}
{% for maintainer in maintainer_by_login %}
<div class="col">
<div class="card shadow rounded w-100">
<div class="card-body">
<h5 class="card-title">
<a href="{{ maintainer.html_url }}" target="_blank"><img class="maintainers-img" src="{{ maintainer.avatar_url }}" alt="{{ maintainer.login }} avatar" /></a>
<a href="{{ maintainer.html_url }}" target="_blank">
@{{ maintainer.login }}
{% if maintainer.name != "None" and maintainer.name != maintainer.login %}<br/><small>({{ maintainer.name }})</small>{% endif %}
</a>
leandrolanzieri marked this conversation as resolved.
Show resolved Hide resolved
</h5>
<ul>
{% if maintainer.owner %}
<li><strong>Is one of the GitHub owners of RIOT</strong></li>
{% endif %}
{% if maintainer.admin %}
<li><strong>Is one of the GitHub admins of RIOT</strong></li>
{% endif %}
{% for area in maintainer.areas %}
<li><tt>{{ area }}</tt></li>
{% endfor %}</ul>
</div>
</div>
</div>
{% endfor %}
</div>
</p>
<p>
This list is generated by combining the information from the maintainers, owners, and
admin teams from the
<a href="https://github.com/RIOT-OS" target="_blank">RIOT GitHub organization</a> and the
<a href="https://github.com/RIOT-OS/RIOT/blob/master/CODEOWNERS" target="_blank">
<tt>CODEOWNERS</tt>
</a> file within the RIOT repository.
</p>

<p>
If you are a maintainer and want to declare ownership for a part of a code base (and
receive notifications on pull requests against it), please add yourself and the path pattern to the
part of the code base you want to be responsible for to
<a href="https://github.com/RIOT-OS/RIOT/blob/master/CODEOWNERS" target="_blank">CODEOWNERS</a>,
and issue a pull request.
</p>
</section><!-- End Board Section -->
</main><!-- End #main -->
Loading