Skip to content

Commit 8280e43

Browse files
committed
Add simple scripting to build specification releases
Add some make driven automation to build releases of the specification and maintain an HTML index of releases. To be driven by a GitHub actions workflow calling make release with, i.e. mkdir build && cd build && make -f ../Makefile release Adds some helper scripts: * get_version.py: is a simple Python script which uses a regex to fetch the version number from a tuf-spec.md -- the script helps avoid dealing with different options between GNU grep (Linux) and BSD grep (macOS and other BSDs) * build_index.py: includes a string which replicates enough of the style of the bikeshed formatted specification to build an appropriately themed HTML page linking to latest, draft, and versioned releases Signed-off-by: Joshua Lock <[email protected]>
1 parent d508ee4 commit 8280e43

File tree

3 files changed

+264
-3
lines changed

3 files changed

+264
-3
lines changed

Makefile

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
SHELL=/bin/bash -o pipefail
2-
.PHONY: local
2+
SPEC_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
3+
.PHONY: spec
34

4-
local: tuf-spec.md
5-
bikeshed spec tuf-spec.md tuf-spec.html
5+
spec: $(SPEC_DIR)/tuf-spec.md
6+
bikeshed spec $(SPEC_DIR)/tuf-spec.md tuf-spec.html
7+
8+
latest: spec
9+
mkdir -p latest
10+
cp tuf-spec.html latest/index.html
11+
12+
versioned: spec
13+
mkdir -p $(shell python3 $(SPEC_DIR)/get_version.py $(SPEC_DIR)/tuf-spec.md)
14+
cp tuf-spec.html $(shell python3 $(SPEC_DIR)/get_version.py $(SPEC_DIR)/tuf-spec.md)/index.html
15+
16+
index:
17+
python3 $(SPEC_DIR)/build_index.py
18+
19+
release: spec latest versioned

build_index.py

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
#!/usr/bin/env python3
2+
3+
"""
4+
<Program Name>
5+
build_index.py
6+
7+
<Author>
8+
Joshua Lock <[email protected]>
9+
10+
<Started>
11+
Feb 1, 2021
12+
13+
<Copyright>
14+
See LICENSE-MIT for licensing information.
15+
16+
<Purpose>
17+
Quick and dirty script to generate an index of published specification
18+
versions.
19+
20+
Style cribbed from the bikeshed W3C theme we are using in our bikeshed
21+
generated specification documents.
22+
"""
23+
24+
import os
25+
import sys
26+
27+
from subprocess import run
28+
29+
html_header = """<!DOCTYPE html>
30+
<html lang="en">
31+
<head>
32+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
33+
<title>The Update Framework Specification</title>
34+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
35+
<style data-fill-with="stylesheet">
36+
body {
37+
counter-reset: example figure issue;
38+
39+
/* Layout */
40+
max-width: 50em; /* limit line length to 50em for readability */
41+
margin: 0 auto; /* center text within page */
42+
padding: 1.6em 1.5em 2em 50px; /* assume 16px font size for downlevel clients */
43+
padding: 1.6em 1.5em 2em calc(26px + 1.5em); /* leave space for status flag */
44+
45+
/* Typography */
46+
line-height: 1.5;
47+
font-family: sans-serif;
48+
widows: 2;
49+
orphans: 2;
50+
word-wrap: break-word;
51+
overflow-wrap: break-word;
52+
hyphens: auto;
53+
54+
color: black;
55+
color: var(--text);
56+
background: white top left fixed no-repeat;
57+
background: var(--bg) top left fixed no-repeat;
58+
background-size: 25px auto;
59+
}
60+
div.head { margin-bottom: 1em; }
61+
div.head h1 {
62+
font-weight: bold;
63+
margin: 0 0 .1em;
64+
font-size: 220%;
65+
}
66+
67+
p {
68+
margin: 1em 0;
69+
}
70+
71+
dd > p:first-child,
72+
li > p:first-child {
73+
margin-top: 0;
74+
}
75+
76+
ul, ol {
77+
margin-left: 0;
78+
padding-left: 2em;
79+
}
80+
81+
li {
82+
margin: 0.25em 0 0.5em;
83+
padding: 0;
84+
}
85+
86+
a {
87+
color: #034575;
88+
color: var(--a-normal-text);
89+
text-decoration: none;
90+
border-bottom: 1px solid #707070;
91+
border-bottom: 1px solid var(--a-normal-underline);
92+
/* Need a bit of extending for it to look okay */
93+
padding: 0 1px 0;
94+
margin: 0 -1px 0;
95+
}
96+
a:visited {
97+
color: #034575;
98+
color: var(--a-visited-text);
99+
border-bottom-color: #bbb;
100+
border-bottom-color: var(--a-visited-underline);
101+
}
102+
103+
a:focus,
104+
a:hover {
105+
background: #f8f8f8;
106+
background: rgba(75%, 75%, 75%, .25);
107+
background: var(--a-hover-bg);
108+
border-bottom-width: 3px;
109+
margin-bottom: -2px;
110+
}
111+
a:active {
112+
color: #c00;
113+
color: var(--a-active-text);
114+
border-color: #c00;
115+
border-color: var(--a-active-underline);
116+
}
117+
118+
h1, h2, h3, h4, h5, h6, dt {
119+
page-break-after: avoid;
120+
page-break-inside: avoid;
121+
font: 100% sans-serif; /* Reset all font styling to clear out UA styles */
122+
font-family: inherit; /* Inherit the font family. */
123+
line-height: 1.2; /* Keep wrapped headings compact */
124+
hyphens: manual; /* Hyphenated headings look weird */
125+
}
126+
h2, h3, h4, h5, h6 {
127+
margin-top: 3rem;
128+
}
129+
h1, h2, h3 {
130+
color: #005A9C;
131+
color: var(--heading-text);
132+
}
133+
h1 { font-size: 170%; }
134+
h2 { font-size: 140%; }
135+
136+
:root {
137+
color-scheme: light dark;
138+
139+
--text: black;
140+
--bg: white;
141+
142+
--heading-text: #005a9c;
143+
144+
--a-normal-text: #034575;
145+
--a-normal-underline: #707070;
146+
--a-visited-text: var(--a-normal-text);
147+
--a-visited-underline: #bbb;
148+
--a-hover-bg: rgba(75%, 75%, 75%, .25);
149+
--a-active-text: #c00;
150+
--a-active-underline: #c00;
151+
}
152+
</style>
153+
</head>
154+
<body class="h-entry">
155+
<div class="head">
156+
<h1 id="title" class="p-name no-ref">The Update Framework Specification</h1>
157+
</div>
158+
<div>
159+
<ul>
160+
"""
161+
162+
html_footer = """</ul>
163+
</body>
164+
</html>
165+
"""
166+
167+
def sanity_check():
168+
branch = None
169+
170+
try:
171+
branch = run("git branch --show-current".split(), capture_output=True).stdout
172+
except Exception:
173+
pass
174+
175+
if branch != b"gh-pages\n":
176+
print(f"build_index.py must be run from the 'gh-pages' branch (on '{branch}'")
177+
sys.exit()
178+
179+
def build_index():
180+
# sanity_check()
181+
182+
html = html_header
183+
184+
html_locations = ['latest', 'draft']
185+
dir_contents = sorted(os.listdir('.'), reverse=True)
186+
for path in dir_contents:
187+
if path.startswith('v'):
188+
if not os.path.exists(f'{path}/index.html'):
189+
continue
190+
html_locations.append(path)
191+
192+
for loc in html_locations:
193+
link = f" <li><a href='{loc}/index.html'>{loc}</a></li>\n"
194+
html = html + link
195+
196+
html = html + html_footer
197+
198+
return html
199+
200+
if __name__ == "__main__":
201+
html = build_index()
202+
with open('index.html', 'w') as index:
203+
index.write(html)

get_version.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env python3
2+
3+
"""
4+
<Program Name>
5+
get_version.py
6+
7+
<Author>
8+
Joshua Lock <[email protected]>
9+
10+
<Started>
11+
Feb 2, 2021
12+
13+
<Copyright>
14+
See LICENSE-MIT for licensing information.
15+
16+
<Purpose>
17+
Quick and dirty script to get the version number from tuf-spec.md
18+
19+
Unfortunately GNU grep and BSD grep take different options...
20+
"""
21+
22+
import re
23+
import sys
24+
25+
pattern = re.compile("VERSION (\d+\.\d+\.\d+)")
26+
27+
def get_version():
28+
out = ''
29+
spec = 'tuf-spec.md'
30+
31+
if (len(sys.argv) > 1):
32+
spec = sys.argv[1]
33+
34+
with open(spec, 'r') as spec:
35+
for line in spec:
36+
for match in re.finditer(pattern, line):
37+
if match.group():
38+
break
39+
out = match.groups()[0]
40+
41+
return f'v{out}'
42+
43+
if __name__ == "__main__":
44+
print(get_version())

0 commit comments

Comments
 (0)