summaryrefslogtreecommitdiff
path: root/scripts/release/repo_init.py
blob: 04c35795ed55bf4ff7a76bd0309dcf82752e23f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
"""
scripts/release/repo_init.py

Run ONCE, ever, by the maintainer, locally. Generates the TUF signing keys
and the initial repository metadata (including root.json, which later gets
bundled into the app via labdaq.spec).

Running this again after the repo already exists is safe (tufup skips
re-creating keys/roles that already exist) but there is normally no reason
to run it more than once per project.

Keys land in ./keystore — never commit that directory (already gitignored).
Back it up somewhere safe and private; losing the root key means you can
never publish another trusted update to existing installs.
"""

import os
from pathlib import Path

from tufup.repo import Repository, RolesDict

# Run from this script's own directory — tufup's config file (.tufup-repo-config)
# and all repo_dir/keys_dir paths are resolved relative to the current working
# directory, so invocation location must be consistent every time.
os.chdir(Path(__file__).resolve().parent)

APP_NAME = "labdaq"

# tufup-example's 1-day timestamp / 7-day snapshot defaults assume an
# automated CI worker re-signs on a schedule. We're signing manually
# (see README.md in this directory), so use longer, human-manageable
# expirations instead. Whichever of these lapses first is the cadence
# you need to re-sign at, even between actual app releases.
EXPIRATION_DAYS = RolesDict(root=365, targets=90, snapshot=90, timestamp=90)


def main():
    # Not using app_version_attr here: tufup's setuptools-based attribute
    # reader resolves dotted paths relative to the current working directory,
    # which we deliberately pin to this script's own directory below (tufup's
    # own config-file/relative-path handling expects that) — the two
    # assumptions conflict. repo_release.py passes the version explicitly
    # instead, which sidesteps this entirely.
    repo = Repository(
        app_name=APP_NAME,
        repo_dir=Path("repository"),
        keys_dir=Path("keystore"),
        expiration_days=EXPIRATION_DAYS,
    )
    repo.initialize()
    repo.save_config()
    print(f"Initialized tufup repo for '{APP_NAME}' in ./repository, keys in ./keystore")
    print("Back up ./keystore now, somewhere private and durable. It is gitignored on purpose.")


if __name__ == "__main__":
    main()