Skip to content

Commit c81a62b

Browse files
committed
feat(stacks): add checker
1 parent 437727c commit c81a62b

4 files changed

Lines changed: 345 additions & 3 deletions

File tree

scripts/checker.py

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
import os
2+
import re
3+
import json
4+
import requests
5+
from datetime import datetime
6+
7+
github_headers = {'Authorization': 'token %s' % os.environ.get("GITHUB_TOKEN")}
8+
9+
repo_info_table = {
10+
"caddy": {
11+
"name": "caddy",
12+
"type": "github",
13+
"owner": "caddyserver",
14+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
15+
},
16+
"envtpl": {
17+
"name": "envtpl",
18+
"type": "github",
19+
"owner": "subfuzion",
20+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
21+
},
22+
"erlang": {
23+
"name": "otp",
24+
"type": "github",
25+
"owner": "erlang",
26+
"match": "^OTP-[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
27+
},
28+
"fluentd": {
29+
"name": "fluentd",
30+
"type": "github",
31+
"owner": "fluent",
32+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
33+
},
34+
"go": {
35+
"name": "go",
36+
"type": "github",
37+
"owner": "golang",
38+
"match": "^go[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
39+
},
40+
"gosu": {
41+
"name": "gosu",
42+
"type": "github",
43+
"owner": "tianon",
44+
"match": "^[0-9]{1,}\.[0-9]{1,}$",
45+
},
46+
"grafana": {
47+
"name": "grafana",
48+
"type": "github",
49+
"owner": "grafana",
50+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
51+
},
52+
"helm": {
53+
"name": "helm",
54+
"type": "github",
55+
"owner": "helm",
56+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
57+
},
58+
"influxdb": {
59+
"name": "influxdb",
60+
"type": "github",
61+
"owner": "influxdata",
62+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
63+
},
64+
"ini-file": {
65+
"name": "ini-file",
66+
"type": "github",
67+
"owner": "bitnami",
68+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
69+
},
70+
"java": {
71+
"name": "jdk",
72+
"type": "github",
73+
"owner": "openjdk",
74+
"match": "^jdk-[0-9]{1,}\+[0-9]{1,}$",
75+
},
76+
"jq": {
77+
"name": "jq",
78+
"type": "github",
79+
"owner": "stedolan",
80+
"match": "^jq-[0-9]{1,}\.[0-9]{1,}\.?[0-9]{0}$",
81+
},
82+
"kubectl": {
83+
"name": "kubectl",
84+
"type": "github",
85+
"owner": "kubernetes",
86+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
87+
},
88+
"mariadb": {
89+
"name": "server",
90+
"type": "github",
91+
"owner": "MariaDB",
92+
"match": "^mariadb-[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
93+
},
94+
"mc": {
95+
"name": "mc",
96+
"type": "github",
97+
"owner": "minio",
98+
"match": "^RELEASE\.[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}-[0-9]{2}-[0-9]{2}Z$",
99+
},
100+
"minio": {
101+
"name": "minio",
102+
"type": "github",
103+
"owner": "minio",
104+
"match": "^RELEASE\.[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}-[0-9]{2}-[0-9]{2}Z$",
105+
},
106+
"nginx": {
107+
"name": "nginx",
108+
"type": "github",
109+
"owner": "nginx",
110+
"match": "^release-[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
111+
},
112+
"node": {
113+
"name": "node",
114+
"type": "github",
115+
"owner": "nodejs",
116+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
117+
},
118+
"pack": {
119+
"name": "pack",
120+
"type": "github",
121+
"owner": "buildpacks",
122+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
123+
},
124+
"php": {
125+
"name": "php-src",
126+
"type": "github",
127+
"owner": "php",
128+
"match": "^php-[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
129+
},
130+
"podman": {
131+
"name": "podman",
132+
"type": "github",
133+
"owner": "containers",
134+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
135+
},
136+
"postgis": {
137+
"name": "postgis",
138+
"type": "github",
139+
"owner": "postgis",
140+
"match": "^[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
141+
},
142+
"postgresql": {
143+
"name": "postgres",
144+
"type": "github",
145+
"owner": "postgres",
146+
"match": "^REL_[0-9]{1,}_[0-9]{1,}$",
147+
},
148+
"python": {
149+
"name": "cpython",
150+
"type": "github",
151+
"owner": "python",
152+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
153+
},
154+
"rabbitmq": {
155+
"name": "rabbitmq-server",
156+
"type": "github",
157+
"owner": "rabbitmq",
158+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
159+
},
160+
"redis": {
161+
"name": "redis",
162+
"type": "github",
163+
"owner": "redis",
164+
"match": "^[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
165+
},
166+
"registry": {
167+
"name": "distribution",
168+
"type": "github",
169+
"owner": "distribution",
170+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
171+
},
172+
"ruby": {
173+
"name": "ruby",
174+
"type": "github",
175+
"owner": "ruby",
176+
"match": "^v[0-9]{1,}_[0-9]{1,}_[0-9]{1,}$",
177+
},
178+
"rust": {
179+
"name": "rust",
180+
"type": "github",
181+
"owner": "rust-lang",
182+
"match": "^[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
183+
},
184+
"telegraf": {
185+
"name": "telegraf",
186+
"type": "github",
187+
"owner": "influxdata",
188+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
189+
},
190+
"wait-for-port": {
191+
"name": "wait-for-port",
192+
"type": "github",
193+
"owner": "bitnami",
194+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
195+
},
196+
"wal-g": {
197+
"name": "wal-g",
198+
"type": "github",
199+
"owner": "wal-g",
200+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.?[0-9]{0}$",
201+
},
202+
"yj": {
203+
"name": "yj",
204+
"type": "github",
205+
"owner": "sclevine",
206+
"match": "^v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$",
207+
},
208+
}
209+
210+
211+
def create_github_tag(stack, tag_name):
212+
sha = requests.get(
213+
"https://api.github.com/repos/drycc/stacks/git/trees/main",
214+
headers=github_headers,
215+
).json()["sha"]
216+
response = requests.post(
217+
"https://api.github.com/repos/drycc/stacks/git/tags",
218+
data = json.dumps({
219+
"tag": tag_name,
220+
"object": sha,
221+
"message": f"new build for {stack}",
222+
"type": "commit",
223+
}),
224+
headers=github_headers,
225+
).json()
226+
params = dict(ref=f"refs/tags/{tag_name}", sha=response['object']['sha'])
227+
response = requests.post(
228+
'https://api.github.com/repos/drycc/stacks/git/refs',
229+
data=json.dumps(params),
230+
headers=github_headers,
231+
)
232+
233+
234+
def create_github_issue(stack, tag_name):
235+
strip_regex = "^[a-zA-Z\-_]{1,}"
236+
replace_regex = "[a-zA-Z\+\-_]{1,}"
237+
version = tag_name
238+
if re.search(strip_regex, tag_name):
239+
version = re.subn(strip_regex, "", tag_name)[0]
240+
if re.search(replace_regex, version):
241+
version = re.subn(replace_regex, ".", version)[0].strip(".")
242+
if requests.get(
243+
f"https://api.github.com/repos/drycc/stacks/git/ref/tags/{stack}@{version}",
244+
headers=github_headers,
245+
).status_code == 404:
246+
create_github_tag(stack, f"{stack}@{version}")
247+
link = f"https://github.com/search?q=org%3Adrycc+install-stack+{stack}&type=code"
248+
requests.post(
249+
"https://api.github.com/repos/drycc/stacks/issues",
250+
data = json.dumps({
251+
"title": f"new build for {stack}@{version}",
252+
"body": f"Please judge whether the [referenced item]({link}) needs to be changed.",
253+
"labels": ["tag"]
254+
}),
255+
headers=github_headers,
256+
)
257+
258+
259+
github_tags_graphql = """
260+
query {
261+
repository(owner: "{owner}", name: "{name}") {
262+
refs(refPrefix: "refs/tags/", first: 10, orderBy: {field: TAG_COMMIT_DATE, direction: DESC}) {
263+
edges {
264+
node {
265+
name
266+
target {
267+
oid
268+
... on Tag {
269+
commitUrl
270+
tagger {
271+
date
272+
}
273+
}
274+
}
275+
}
276+
}
277+
}
278+
}
279+
}
280+
"""
281+
282+
def check_github_version(stack):
283+
info = repo_info_table[stack]
284+
response = requests.post(
285+
"https://api.github.com/graphql",
286+
data=json.dumps({
287+
"query": github_tags_graphql.replace(
288+
"{owner}", info["owner"]).replace("{name}", info["name"]),
289+
}),
290+
headers=github_headers,
291+
)
292+
for tag in response.json()["data"]["repository"]["refs"]["edges"]:
293+
if "tagger" in tag["node"]["target"]:
294+
date = datetime.strptime(
295+
tag["node"]["target"]["tagger"]["date"][:19], "%Y-%m-%dT%H:%M:%S")
296+
else:
297+
date = datetime.strptime(
298+
requests.get(
299+
"https://api.github.com/repos/{}/{}/commits/{}".format(
300+
info["owner"], info["name"], tag["node"]["target"]["oid"]
301+
), headers=github_headers
302+
).json()["commit"]["author"]["date"][:19],
303+
"%Y-%m-%dT%H:%M:%S"
304+
)
305+
if re.match(info["match"], tag["node"]["name"]):
306+
if (datetime.utcnow() - date).days < 5:
307+
create_github_issue(stack, tag["node"]["name"])
308+
else:
309+
break
310+
311+
312+
def main():
313+
for stack in os.listdir(os.path.join(os.path.dirname(__file__), "..", "stacks")):
314+
if stack not in repo_info_table:
315+
raise NotImplementedError(f"{stack} not in repo_info_table")
316+
else:
317+
repo_type = repo_info_table[stack]["type"]
318+
if repo_type != "github":
319+
raise NotImplementedError(f"{repo_type} NotImplemented")
320+
else:
321+
check_github_version(stack)
322+
323+
324+
if __name__ == "__main__":
325+
main()

scripts/storage.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@
1313
'drycc'
1414
)
1515

16+
symlink_table = {
17+
"go": ["1.16", "1.17", "1.18"],
18+
"java": ["8", "11", "17", "18", "19"],
19+
"node": ["12", "14", "16"],
20+
"php": ["7.3", "7.4", "8.0", "8.1"],
21+
"python": ["2.7", "3.7", "3.8", "3.9", "3.10"],
22+
"ruby": ["2.6", "3.7", "3.0", "3.1"],
23+
"rust": ["1"],
24+
}
25+
1626

1727
def upload(filename, filepath):
1828
with open(filepath, "rb") as f:
@@ -27,6 +37,11 @@ def upload_list(stack_name, dist_dir):
2737
filename = os.path.join("stacks", stack_name, _filename)
2838
filepath = os.path.join(root, _filename)
2939
upload(filename, filepath)
40+
if stack_name in symlink_table:
41+
for symlink_version in symlink_table[stack_name]:
42+
prefix = f"stacks/{stack_name}/{stack_name}-{symlink_version}"
43+
if filename.startswith(prefix):
44+
symlink(stack_name, symlink_version)
3045

3146

3247
def symlink(stack_name, version):
@@ -38,7 +53,7 @@ def symlink(stack_name, version):
3853
object_list.sort(reverse=True)
3954
for obj in object_list:
4055
name = f"stacks/{stack_name}/{stack_name}-{version}"
41-
symlink = re.sub("%s.[0-9]{1,}" % name, name, obj)
56+
symlink = re.sub("%s.([0-9]\.?){1,}" % name, name, obj)
4257
if symlink != obj and symlink not in symlink_list:
4358
bucket.put_symlink(obj, symlink)
4459
symlink_list.append(symlink)

stacks/mc/build.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ function build() {
88
generate-stack-path
99
BIN_DIR="${DATA_DIR}"/bin
1010
mkdir -p "${BIN_DIR}"
11-
curl -fsSL -o "${BIN_DIR}"/"${STACK_NAME}" https://dl.min.io/client/mc/release/linux-${OS_ARCH}/mc.${STACK_VERSION}
11+
version=$(echo ${STACK_VERSION} | awk -F "." '{print "RELEASE."$1"-"$2"-"$3"T"$4"-"$5"-"$6"Z"}')
12+
curl -fsSL -o "${BIN_DIR}"/"${STACK_NAME}" https://dl.min.io/client/mc/release/linux-${OS_ARCH}/mc.${version}
1213
chmod +x "${BIN_DIR}"/"${STACK_NAME}"
1314
}
1415

stacks/minio/build.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ function build() {
88
generate-stack-path
99
BIN_DIR="${DATA_DIR}"/bin
1010
mkdir -p "${BIN_DIR}"
11-
curl -fsSL -o "${BIN_DIR}"/"${STACK_NAME}" https://dl.min.io/server/minio/release/linux-${OS_ARCH}/minio.${STACK_VERSION}
11+
version=$(echo ${STACK_VERSION} | awk -F "." '{print "RELEASE."$1"-"$2"-"$3"T"$4"-"$5"-"$6"Z"}')
12+
curl -fsSL -o "${BIN_DIR}"/"${STACK_NAME}" https://dl.min.io/server/minio/release/linux-${OS_ARCH}/minio.${version}
1213
chmod +x "${BIN_DIR}"/"${STACK_NAME}"
1314
}
1415

0 commit comments

Comments
 (0)