k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/hack/verify-publishing-bot.py (about) 1 #!/usr/bin/env python3 2 3 # Copyright 2019 The Kubernetes Authors. 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 import fnmatch 18 import os 19 import sys 20 import json 21 22 23 def get_gomod_dependencies(rootdir, components): 24 all_dependencies = {} 25 for component in components: 26 with open(os.path.join(rootdir, component, "go.mod")) as f: 27 print((component + " dependencies")) 28 all_dependencies[component] = [] 29 lines = list(set(f)) 30 lines.sort() 31 for line in lines: 32 for dep in components: 33 if dep == component: 34 continue 35 if ("k8s.io/" + dep + " =>") not in line: 36 continue 37 print(("\t"+dep)) 38 if dep not in all_dependencies[component]: 39 all_dependencies[component].append(dep) 40 return all_dependencies 41 42 43 def get_rules_dependencies(rules_file): 44 import yaml 45 with open(rules_file) as f: 46 data = yaml.safe_load(f) 47 return data 48 49 50 def main(): 51 rootdir = os.path.dirname(__file__) + "/../" 52 rootdir = os.path.abspath(rootdir) 53 54 components = [] 55 for component in os.listdir(rootdir + '/staging/src/k8s.io/'): 56 components.append(component) 57 components.sort() 58 59 rules_file = "/staging/publishing/rules.yaml" 60 try: 61 import yaml 62 except ImportError: 63 print(("Please install missing pyyaml module and re-run %s" % sys.argv[0])) 64 sys.exit(1) 65 rules_dependencies = get_rules_dependencies(rootdir + rules_file) 66 67 gomod_dependencies = get_gomod_dependencies(rootdir + '/staging/src/k8s.io/', components) 68 69 processed_repos = [] 70 for rule in rules_dependencies["rules"]: 71 branch = rule["branches"][0] 72 73 # If this no longer exists in master 74 if rule["destination"] not in gomod_dependencies: 75 # Make sure we don't include a rule to publish it from master 76 for branch in rule["branches"]: 77 if branch["name"] == "master": 78 raise Exception("cannot find master branch for destination %s" % rule["destination"]) 79 # And skip validation of publishing rules for it 80 continue 81 82 for item in rule["branches"]: 83 if "dir" in item["source"]: 84 raise Exception("use of deprecated `dir` field in rules for `%s`" % (rule["destination"])) 85 if len(item["source"]["dirs"]) > 1: 86 raise Exception("cannot have more than one directory (`%s`) per source branch `%s` of `%s`" % 87 (item["source"]["dirs"], item["source"]["branch"], rule["destination"]) 88 ) 89 if not item["source"]["dirs"][0].endswith(rule["destination"]): 90 raise Exception("copy/paste error `%s` refers to `%s`" % (rule["destination"],item["source"]["dir"])) 91 92 if branch["name"] != "master": 93 raise Exception("cannot find master branch for destination %s" % rule["destination"]) 94 if branch["source"]["branch"] != "master": 95 raise Exception("cannot find master source branch for destination %s" % rule["destination"]) 96 97 # we specify the go version for all master branches through `default-go-version` 98 # so ensure we don't specify explicit go version for master branch in rules 99 if "go" in branch: 100 raise Exception("go version must not be specified for master branch for destination %s" % rule["destination"]) 101 102 print(("processing : %s" % rule["destination"])) 103 if rule["destination"] not in gomod_dependencies: 104 raise Exception("missing go.mod for %s" % rule["destination"]) 105 processed_repos.append(rule["destination"]) 106 processed_deps = [] 107 for dep in set(gomod_dependencies[rule["destination"]]): 108 found = False 109 if "dependencies" in branch: 110 for dep2 in branch["dependencies"]: 111 processed_deps.append(dep2["repository"]) 112 if dep2["branch"] != "master": 113 raise Exception("Looking for master branch and found : %s for destination", dep2, 114 rule["destination"]) 115 if dep2["repository"] == dep: 116 found = True 117 else: 118 raise Exception( 119 "Please add %s as dependencies under destination %s in %s" % (gomod_dependencies[rule["destination"]], rule["destination"], rules_file)) 120 if not found: 121 raise Exception("Please add %s as a dependency under destination %s in %s" % (dep, rule["destination"], rules_file)) 122 else: 123 print((" found dependency %s" % dep)) 124 extraDeps = set(processed_deps) - set(gomod_dependencies[rule["destination"]]) 125 if len(extraDeps) > 0: 126 raise Exception("extra dependencies in rules for %s: %s" % (rule["destination"], ','.join(str(s) for s in extraDeps))) 127 items = set(gomod_dependencies.keys()) - set(processed_repos) 128 if len(items) > 0: 129 raise Exception("missing rules for %s" % ','.join(str(s) for s in items)) 130 print("Done.") 131 132 133 if __name__ == "__main__": 134 sys.exit(main())