forked from theupdateframework/specification
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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]>
- Loading branch information
Showing
3 changed files
with
264 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,19 @@ | ||
SHELL=/bin/bash -o pipefail | ||
.PHONY: local | ||
SPEC_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) | ||
.PHONY: spec | ||
|
||
local: tuf-spec.md | ||
bikeshed spec tuf-spec.md tuf-spec.html | ||
spec: $(SPEC_DIR)/tuf-spec.md | ||
bikeshed spec $(SPEC_DIR)/tuf-spec.md tuf-spec.html | ||
|
||
latest: spec | ||
mkdir -p latest | ||
cp tuf-spec.html latest/index.html | ||
|
||
versioned: spec | ||
mkdir -p $(shell python3 $(SPEC_DIR)/get_version.py $(SPEC_DIR)/tuf-spec.md) | ||
cp tuf-spec.html $(shell python3 $(SPEC_DIR)/get_version.py $(SPEC_DIR)/tuf-spec.md)/index.html | ||
|
||
index: | ||
python3 $(SPEC_DIR)/build_index.py | ||
|
||
release: spec latest versioned |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
#!/usr/bin/env python3 | ||
|
||
""" | ||
<Program Name> | ||
build_index.py | ||
<Author> | ||
Joshua Lock <[email protected]> | ||
<Started> | ||
Feb 1, 2021 | ||
<Copyright> | ||
See LICENSE-MIT for licensing information. | ||
<Purpose> | ||
Quick and dirty script to generate an index of published specification | ||
versions. | ||
Style cribbed from the bikeshed W3C theme we are using in our bikeshed | ||
generated specification documents. | ||
""" | ||
|
||
import os | ||
import sys | ||
|
||
from subprocess import run | ||
|
||
html_header = """<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | ||
<title>The Update Framework Specification</title> | ||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | ||
<style data-fill-with="stylesheet"> | ||
body { | ||
counter-reset: example figure issue; | ||
/* Layout */ | ||
max-width: 50em; /* limit line length to 50em for readability */ | ||
margin: 0 auto; /* center text within page */ | ||
padding: 1.6em 1.5em 2em 50px; /* assume 16px font size for downlevel clients */ | ||
padding: 1.6em 1.5em 2em calc(26px + 1.5em); /* leave space for status flag */ | ||
/* Typography */ | ||
line-height: 1.5; | ||
font-family: sans-serif; | ||
widows: 2; | ||
orphans: 2; | ||
word-wrap: break-word; | ||
overflow-wrap: break-word; | ||
hyphens: auto; | ||
color: black; | ||
color: var(--text); | ||
background: white top left fixed no-repeat; | ||
background: var(--bg) top left fixed no-repeat; | ||
background-size: 25px auto; | ||
} | ||
div.head { margin-bottom: 1em; } | ||
div.head h1 { | ||
font-weight: bold; | ||
margin: 0 0 .1em; | ||
font-size: 220%; | ||
} | ||
p { | ||
margin: 1em 0; | ||
} | ||
dd > p:first-child, | ||
li > p:first-child { | ||
margin-top: 0; | ||
} | ||
ul, ol { | ||
margin-left: 0; | ||
padding-left: 2em; | ||
} | ||
li { | ||
margin: 0.25em 0 0.5em; | ||
padding: 0; | ||
} | ||
a { | ||
color: #034575; | ||
color: var(--a-normal-text); | ||
text-decoration: none; | ||
border-bottom: 1px solid #707070; | ||
border-bottom: 1px solid var(--a-normal-underline); | ||
/* Need a bit of extending for it to look okay */ | ||
padding: 0 1px 0; | ||
margin: 0 -1px 0; | ||
} | ||
a:visited { | ||
color: #034575; | ||
color: var(--a-visited-text); | ||
border-bottom-color: #bbb; | ||
border-bottom-color: var(--a-visited-underline); | ||
} | ||
a:focus, | ||
a:hover { | ||
background: #f8f8f8; | ||
background: rgba(75%, 75%, 75%, .25); | ||
background: var(--a-hover-bg); | ||
border-bottom-width: 3px; | ||
margin-bottom: -2px; | ||
} | ||
a:active { | ||
color: #c00; | ||
color: var(--a-active-text); | ||
border-color: #c00; | ||
border-color: var(--a-active-underline); | ||
} | ||
h1, h2, h3, h4, h5, h6, dt { | ||
page-break-after: avoid; | ||
page-break-inside: avoid; | ||
font: 100% sans-serif; /* Reset all font styling to clear out UA styles */ | ||
font-family: inherit; /* Inherit the font family. */ | ||
line-height: 1.2; /* Keep wrapped headings compact */ | ||
hyphens: manual; /* Hyphenated headings look weird */ | ||
} | ||
h2, h3, h4, h5, h6 { | ||
margin-top: 3rem; | ||
} | ||
h1, h2, h3 { | ||
color: #005A9C; | ||
color: var(--heading-text); | ||
} | ||
h1 { font-size: 170%; } | ||
h2 { font-size: 140%; } | ||
:root { | ||
color-scheme: light dark; | ||
--text: black; | ||
--bg: white; | ||
--heading-text: #005a9c; | ||
--a-normal-text: #034575; | ||
--a-normal-underline: #707070; | ||
--a-visited-text: var(--a-normal-text); | ||
--a-visited-underline: #bbb; | ||
--a-hover-bg: rgba(75%, 75%, 75%, .25); | ||
--a-active-text: #c00; | ||
--a-active-underline: #c00; | ||
} | ||
</style> | ||
</head> | ||
<body class="h-entry"> | ||
<div class="head"> | ||
<h1 id="title" class="p-name no-ref">The Update Framework Specification</h1> | ||
</div> | ||
<div> | ||
<ul> | ||
""" | ||
|
||
html_footer = """</ul> | ||
</body> | ||
</html> | ||
""" | ||
|
||
def sanity_check(): | ||
branch = None | ||
|
||
try: | ||
branch = run("git branch --show-current".split(), capture_output=True).stdout | ||
except Exception: | ||
pass | ||
|
||
if branch != b"gh-pages\n": | ||
print(f"build_index.py must be run from the 'gh-pages' branch (on '{branch}'") | ||
sys.exit() | ||
|
||
def build_index(): | ||
# sanity_check() | ||
|
||
html = html_header | ||
|
||
html_locations = ['latest', 'draft'] | ||
dir_contents = sorted(os.listdir('.'), reverse=True) | ||
for path in dir_contents: | ||
if path.startswith('v'): | ||
if not os.path.exists(f'{path}/index.html'): | ||
continue | ||
html_locations.append(path) | ||
|
||
for loc in html_locations: | ||
link = f" <li><a href='{loc}/index.html'>{loc}</a></li>\n" | ||
html = html + link | ||
|
||
html = html + html_footer | ||
|
||
return html | ||
|
||
if __name__ == "__main__": | ||
html = build_index() | ||
with open('index.html', 'w') as index: | ||
index.write(html) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#!/usr/bin/env python3 | ||
|
||
""" | ||
<Program Name> | ||
get_version.py | ||
<Author> | ||
Joshua Lock <[email protected]> | ||
<Started> | ||
Feb 2, 2021 | ||
<Copyright> | ||
See LICENSE-MIT for licensing information. | ||
<Purpose> | ||
Quick and dirty script to get the version number from tuf-spec.md | ||
Unfortunately GNU grep and BSD grep take different options... | ||
""" | ||
|
||
import re | ||
import sys | ||
|
||
pattern = re.compile("VERSION (\d+\.\d+\.\d+)") | ||
|
||
def get_version(): | ||
out = '' | ||
spec = 'tuf-spec.md' | ||
|
||
if (len(sys.argv) > 1): | ||
spec = sys.argv[1] | ||
|
||
with open(spec, 'r') as spec: | ||
for line in spec: | ||
for match in re.finditer(pattern, line): | ||
if match.group(): | ||
break | ||
out = match.groups()[0] | ||
|
||
return f'v{out}' | ||
|
||
if __name__ == "__main__": | ||
print(get_version()) |