Skip to content

Commit 8a37da3

Browse files
fix: remove invalid gh-pages key from .asf.yaml and add CI validation (#159)
The gh-pages key under github.features is not in the ASF .asf.yaml schema, causing ASF infra errors after merge. Add a validation script to catch such issues in CI before merge.
1 parent 0b08970 commit 8a37da3

3 files changed

Lines changed: 154 additions & 2 deletions

File tree

.asf.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ github:
3737
discussions: true
3838
wiki: false
3939
projects: false
40-
gh-pages:
41-
whatever: Just a placeholder to make it take effects
4240
protected_branches:
4341
main:
4442
required_pull_request_reviews:

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ jobs:
3535
steps:
3636
- uses: actions/checkout@v4
3737

38+
- name: Validate .asf.yaml
39+
run: python3 scripts/validate_asf_yaml.py
40+
3841
- name: Check License Header
3942
uses: apache/skywalking-eyes/header@v0.6.0
4043

scripts/validate_asf_yaml.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
#!/usr/bin/env python3
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
19+
"""Validate .asf.yaml against known ASF infrastructure schema.
20+
21+
Reference: https://github.com/apache/infrastructure-asfyaml/blob/main/README.md
22+
"""
23+
24+
import sys
25+
import yaml
26+
27+
ASF_YAML_PATH = ".asf.yaml"
28+
29+
# Known top-level keys in .asf.yaml
30+
VALID_TOP_LEVEL_KEYS = {
31+
"github",
32+
"notifications",
33+
"staging",
34+
"publish",
35+
"pelican",
36+
}
37+
38+
# Known keys under 'github'
39+
VALID_GITHUB_KEYS = {
40+
"description",
41+
"homepage",
42+
"labels",
43+
"features",
44+
"enabled_merge_buttons",
45+
"protected_branches",
46+
"collaborators",
47+
"autolinks",
48+
"environments",
49+
"dependabot_alerts",
50+
"dependabot_updates",
51+
"code_scanning",
52+
"del_branch_on_merge",
53+
"ghp_branch",
54+
"ghp_path",
55+
}
56+
57+
# Known keys under 'github.features'
58+
VALID_FEATURES_KEYS = {
59+
"issues",
60+
"discussions",
61+
"wiki",
62+
"projects",
63+
}
64+
65+
# Known keys under 'github.enabled_merge_buttons'
66+
VALID_MERGE_BUTTON_KEYS = {
67+
"squash",
68+
"merge",
69+
"rebase",
70+
}
71+
72+
# Known keys under 'notifications'
73+
VALID_NOTIFICATIONS_KEYS = {
74+
"commits",
75+
"issues",
76+
"pullrequests",
77+
"jira_options",
78+
"jobs",
79+
"discussions",
80+
}
81+
82+
83+
def validate():
84+
errors = []
85+
86+
try:
87+
with open(ASF_YAML_PATH, "r") as f:
88+
data = yaml.safe_load(f)
89+
except FileNotFoundError:
90+
print(f"SKIP: {ASF_YAML_PATH} not found")
91+
return 0
92+
except yaml.YAMLError as e:
93+
print(f"ERROR: Invalid YAML syntax in {ASF_YAML_PATH}: {e}")
94+
return 1
95+
96+
if not isinstance(data, dict):
97+
print(f"ERROR: {ASF_YAML_PATH} root must be a mapping")
98+
return 1
99+
100+
# Check top-level keys
101+
for key in data:
102+
if key not in VALID_TOP_LEVEL_KEYS:
103+
errors.append(f"unexpected top-level key '{key}'")
104+
105+
github = data.get("github")
106+
if isinstance(github, dict):
107+
for key in github:
108+
if key not in VALID_GITHUB_KEYS:
109+
errors.append(f"unexpected key 'github.{key}'")
110+
111+
features = github.get("features")
112+
if isinstance(features, dict):
113+
for key in features:
114+
if key not in VALID_FEATURES_KEYS:
115+
errors.append(
116+
f"unexpected key 'github.features.{key}' "
117+
f"(allowed: {', '.join(sorted(VALID_FEATURES_KEYS))})"
118+
)
119+
elif not isinstance(features[key], bool):
120+
errors.append(
121+
f"'github.features.{key}' must be a boolean, "
122+
f"got {type(features[key]).__name__}"
123+
)
124+
125+
merge_buttons = github.get("enabled_merge_buttons")
126+
if isinstance(merge_buttons, dict):
127+
for key in merge_buttons:
128+
if key not in VALID_MERGE_BUTTON_KEYS:
129+
errors.append(
130+
f"unexpected key 'github.enabled_merge_buttons.{key}' "
131+
f"(allowed: {', '.join(sorted(VALID_MERGE_BUTTON_KEYS))})"
132+
)
133+
134+
notifications = data.get("notifications")
135+
if isinstance(notifications, dict):
136+
for key in notifications:
137+
if key not in VALID_NOTIFICATIONS_KEYS:
138+
errors.append(f"unexpected key 'notifications.{key}'")
139+
140+
if errors:
141+
print(f"ERROR: {ASF_YAML_PATH} validation failed:")
142+
for err in errors:
143+
print(f" - {err}")
144+
return 1
145+
146+
print(f"OK: {ASF_YAML_PATH} is valid")
147+
return 0
148+
149+
150+
if __name__ == "__main__":
151+
sys.exit(validate())

0 commit comments

Comments
 (0)