|
|
|
@ -1,17 +1,22 @@ |
|
|
|
|
#!/usr/bin/env python3 |
|
|
|
|
from dataclasses import dataclass |
|
|
|
|
import json |
|
|
|
|
import os |
|
|
|
|
import pathlib |
|
|
|
|
import subprocess |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from openpilot.common.basedir import BASEDIR |
|
|
|
|
from openpilot.common.swaglog import cloudlog |
|
|
|
|
from openpilot.common.utils import cache |
|
|
|
|
from openpilot.common.git import get_origin, get_branch, get_short_branch, get_normalized_origin, get_commit_date |
|
|
|
|
from openpilot.common.git import get_commit, get_origin, get_branch, get_short_branch, get_commit_date |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RELEASE_BRANCHES = ['release3-staging', 'release3', 'nightly'] |
|
|
|
|
TESTED_BRANCHES = RELEASE_BRANCHES + ['devel', 'devel-staging'] |
|
|
|
|
|
|
|
|
|
BUILD_METADATA_FILENAME = "build.json" |
|
|
|
|
|
|
|
|
|
training_version: bytes = b"0.2.0" |
|
|
|
|
terms_version: bytes = b"2" |
|
|
|
|
|
|
|
|
@ -27,31 +32,13 @@ def get_release_notes(path: str = BASEDIR) -> str: |
|
|
|
|
return f.read().split('\n\n', 1)[0] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@cache |
|
|
|
|
def get_short_version() -> str: |
|
|
|
|
return get_version().split('-')[0] |
|
|
|
|
|
|
|
|
|
@cache |
|
|
|
|
def is_prebuilt() -> bool: |
|
|
|
|
return os.path.exists(os.path.join(BASEDIR, 'prebuilt')) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@cache |
|
|
|
|
def is_comma_remote() -> bool: |
|
|
|
|
# note to fork maintainers, this is used for release metrics. please do not |
|
|
|
|
# touch this to get rid of the orange startup alert. there's better ways to do that |
|
|
|
|
return get_normalized_origin() == "github.com/commaai/openpilot" |
|
|
|
|
|
|
|
|
|
@cache |
|
|
|
|
def is_tested_branch() -> bool: |
|
|
|
|
return get_short_branch() in TESTED_BRANCHES |
|
|
|
|
|
|
|
|
|
@cache |
|
|
|
|
def is_release_branch() -> bool: |
|
|
|
|
return get_short_branch() in RELEASE_BRANCHES |
|
|
|
|
|
|
|
|
|
@cache |
|
|
|
|
def is_dirty() -> bool: |
|
|
|
|
def is_dirty(cwd: str = None) -> bool: |
|
|
|
|
origin = get_origin() |
|
|
|
|
branch = get_branch() |
|
|
|
|
if not origin or not branch: |
|
|
|
@ -63,11 +50,11 @@ def is_dirty() -> bool: |
|
|
|
|
if not is_prebuilt(): |
|
|
|
|
# This is needed otherwise touched files might show up as modified |
|
|
|
|
try: |
|
|
|
|
subprocess.check_call(["git", "update-index", "--refresh"]) |
|
|
|
|
subprocess.check_call(["git", "update-index", "--refresh"], cwd=cwd) |
|
|
|
|
except subprocess.CalledProcessError: |
|
|
|
|
pass |
|
|
|
|
|
|
|
|
|
dirty = (subprocess.call(["git", "diff-index", "--quiet", branch, "--"]) != 0) |
|
|
|
|
dirty = (subprocess.call(["git", "diff-index", "--quiet", branch, "--"], cwd=cwd) != 0) |
|
|
|
|
except subprocess.CalledProcessError: |
|
|
|
|
cloudlog.exception("git subprocess failed while checking dirty") |
|
|
|
|
dirty = True |
|
|
|
@ -75,6 +62,81 @@ def is_dirty() -> bool: |
|
|
|
|
return dirty |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True) |
|
|
|
|
class OpenpilotMetadata: |
|
|
|
|
version: str |
|
|
|
|
release_notes: str |
|
|
|
|
git_commit: str |
|
|
|
|
git_origin: str |
|
|
|
|
git_commit_date: str |
|
|
|
|
git_dirty: bool |
|
|
|
|
|
|
|
|
|
@property |
|
|
|
|
def short_version(self) -> str: |
|
|
|
|
return self.version.split('-')[0] |
|
|
|
|
|
|
|
|
|
@property |
|
|
|
|
def comma_remote(self) -> bool: |
|
|
|
|
# note to fork maintainers, this is used for release metrics. please do not |
|
|
|
|
# touch this to get rid of the orange startup alert. there's better ways to do that |
|
|
|
|
return self.git_normalized_origin == "github.com/commaai/openpilot" |
|
|
|
|
|
|
|
|
|
@property |
|
|
|
|
def git_normalized_origin(self) -> str: |
|
|
|
|
return self.git_origin \ |
|
|
|
|
.replace("git@", "", 1) \ |
|
|
|
|
.replace(".git", "", 1) \ |
|
|
|
|
.replace("https://", "", 1) \ |
|
|
|
|
.replace(":", "/", 1) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True) |
|
|
|
|
class BuildMetadata: |
|
|
|
|
channel: str |
|
|
|
|
openpilot: OpenpilotMetadata |
|
|
|
|
|
|
|
|
|
@property |
|
|
|
|
def tested_channel(self) -> bool: |
|
|
|
|
return self.channel in TESTED_BRANCHES |
|
|
|
|
|
|
|
|
|
@property |
|
|
|
|
def release_channel(self) -> bool: |
|
|
|
|
return self.channel in RELEASE_BRANCHES |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_build_metadata(path: str = BASEDIR) -> BuildMetadata: |
|
|
|
|
build_metadata_path = pathlib.Path(path) / BUILD_METADATA_FILENAME |
|
|
|
|
|
|
|
|
|
if build_metadata_path.exists(): |
|
|
|
|
build_metadata = json.loads(build_metadata_path.read_text()) |
|
|
|
|
openpilot_metadata = build_metadata.get("openpilot", {}) |
|
|
|
|
|
|
|
|
|
channel = build_metadata.get("channel", "unknown") |
|
|
|
|
version = openpilot_metadata.get("version", "unknown") |
|
|
|
|
release_notes = openpilot_metadata.get("release_notes", "unknown") |
|
|
|
|
git_commit = openpilot_metadata.get("git_commit", "unknown") |
|
|
|
|
git_origin = openpilot_metadata.get("git_origin", "unknown") |
|
|
|
|
git_commit_date = openpilot_metadata.get("git_commit_date", "unknown") |
|
|
|
|
return BuildMetadata(channel, |
|
|
|
|
OpenpilotMetadata( |
|
|
|
|
version=version, |
|
|
|
|
release_notes=release_notes, |
|
|
|
|
git_commit=git_commit, |
|
|
|
|
git_origin=git_origin, |
|
|
|
|
git_commit_date=git_commit_date, |
|
|
|
|
git_dirty=False)) |
|
|
|
|
|
|
|
|
|
git_folder = pathlib.Path(path) / ".git" |
|
|
|
|
|
|
|
|
|
if git_folder.exists(): |
|
|
|
|
return BuildMetadata(get_short_branch(path), OpenpilotMetadata(get_version(path), get_release_notes(path), get_commit(path), \ |
|
|
|
|
get_origin(path), get_commit_date(path), is_dirty(path))) |
|
|
|
|
|
|
|
|
|
cloudlog.exception("unable to get build metadata") |
|
|
|
|
raise Exception("invalid build metadata") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|
from openpilot.common.params import Params |
|
|
|
|
|
|
|
|
@ -82,12 +144,4 @@ if __name__ == "__main__": |
|
|
|
|
params.put("TermsVersion", terms_version) |
|
|
|
|
params.put("TrainingVersion", training_version) |
|
|
|
|
|
|
|
|
|
print(f"Dirty: {is_dirty()}") |
|
|
|
|
print(f"Version: {get_version()}") |
|
|
|
|
print(f"Short version: {get_short_version()}") |
|
|
|
|
print(f"Origin: {get_origin()}") |
|
|
|
|
print(f"Normalized origin: {get_normalized_origin()}") |
|
|
|
|
print(f"Branch: {get_branch()}") |
|
|
|
|
print(f"Short branch: {get_short_branch()}") |
|
|
|
|
print(f"Prebuilt: {is_prebuilt()}") |
|
|
|
|
print(f"Commit date: {get_commit_date()}") |
|
|
|
|
print(get_build_metadata()) |
|
|
|
|