Skip to content

Commit 418f5c3

Browse files
Merge pull request coreos#58 from jlebon/pr/versionary
NO-JIRA: Add versionary script
2 parents 6616a6e + 7fd2d95 commit 418f5c3

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

versionary

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#!/usr/bin/python3 -u
2+
3+
'''
4+
Implements versioning for RHEL CoreOS and CentOS Stream CoreOS. Initially based
5+
on the Fedora CoreOS versionary script.
6+
'''
7+
8+
import argparse
9+
import json
10+
import os
11+
import re
12+
import subprocess
13+
import sys
14+
import time
15+
import yaml
16+
17+
from datetime import datetime
18+
19+
20+
def main():
21+
args = parse_args()
22+
if args.workdir is not None:
23+
os.chdir(args.workdir)
24+
assert os.path.isdir('builds'), 'Missing builds/ dir'
25+
26+
manifest = get_flattened_manifest()
27+
28+
# we'll want to move the source of truth for this somewhere else in the future but for now...
29+
prefix = manifest['automatic-version-prefix']
30+
placeholder = '<date:%Y%m%d>'
31+
assert placeholder in prefix
32+
dt = datetime.now()
33+
xyz = prefix.replace(placeholder, dt.strftime('%Y%m%d'))
34+
x, y, z = map(int, xyz.split('.'))
35+
n = get_next_iteration(x, y, z, args.last_version)
36+
dev = '.dev' if args.dev else ''
37+
38+
print(f'{xyz}-{n}{dev}')
39+
40+
41+
def parse_args():
42+
parser = argparse.ArgumentParser()
43+
parser.add_argument('--workdir', help="path to cosa workdir")
44+
parser.add_argument('--last-version', help="override last version (for testing)")
45+
parser.add_argument('--dev', action='store_true', help="generate a developer version")
46+
return parser.parse_args()
47+
48+
49+
def get_next_iteration(x, y, z, last_version_override):
50+
try:
51+
with open('builds/builds.json') as f:
52+
builds = json.load(f)
53+
except FileNotFoundError:
54+
builds = {'builds': []}
55+
56+
if last_version_override is not None:
57+
last_version = last_version_override
58+
else:
59+
if len(builds['builds']) == 0:
60+
eprint("n: 0 (no previous builds)")
61+
return 0
62+
63+
last_version = builds['builds'][0]['id']
64+
65+
last_version_tuple = parse_version(last_version)
66+
67+
if not last_version_tuple:
68+
eprint(f"n: 0 (previous version {last_version} does not match scheme)")
69+
return 0
70+
71+
if (x, y, z) != last_version_tuple[:3]:
72+
eprint(f"n: 0 (previous version {last_version} x.y.z does not match)")
73+
return 0
74+
75+
n = last_version_tuple[3] + 1
76+
eprint(f"n: {n} (incremented from previous version {last_version})")
77+
return n
78+
79+
80+
def get_flattened_manifest():
81+
try:
82+
with open('src/config.json') as f:
83+
j = json.load(f)
84+
variant = j["coreos-assembler.config-variant"]
85+
manifest = f'src/config/manifest-{variant}.yaml'
86+
except FileNotFoundError:
87+
manifest = 'src/config/manifest.yaml'
88+
return yaml.safe_load(
89+
subprocess.check_output(['rpm-ostree', 'compose', 'tree',
90+
'--print-only', manifest]))
91+
92+
93+
def parse_version(version):
94+
# since RHCOS/SCOS follows semver, we could actually instead use a library
95+
# for this, but we do actually only expect a particular subset in our case
96+
m = re.match(r'^([0-9]+)\.([0-9]+)\.([0-9]{8})-([0-9]+)(\.dev)?$', version)
97+
if m is None:
98+
return None
99+
# sanity-check date
100+
try:
101+
time.strptime(m.group(3), '%Y%m%d')
102+
except ValueError:
103+
return None
104+
return tuple(map(int, m.groups()[:4]))
105+
106+
107+
def eprint(*args):
108+
print(*args, file=sys.stderr)
109+
110+
111+
if __name__ == "__main__":
112+
sys.exit(main())

0 commit comments

Comments
 (0)