A fork of https://github.com/crosspoint-reader/crosspoint-reader
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: Add git branch to version information on settings screen (#1225)

## Summary

* **What is the goal of this PR?** During my development I am frequently
jumping from branch to branch flashing test versions on my device. It
becomes sometimes quite difficult to figure out which version of the
software I am currently looking at.

* **What changes are included?**
- Dev builds now display the current git branch in the version string
shown on the Settings screen (e.g. 1.1.0-dev+feat-my-feature), making it
easier to identify which firmware is running on the device when
switching between branches frequently.
- Release, RC, and slim builds are unaffected — they continue to set
their version string statically in platformio.ini.
<img width="480" height="800" alt="after"
src="https://github.com/user-attachments/assets/d2ab3d69-ab6b-47a1-8eb7-1b40b1d3b106"
/>


## Additional Context

A new PlatformIO pre-build script (scripts/git_branch.py) runs
automatically before every dev build. It reads the base version from the
[crosspoint] section of platformio.ini, queries git rev-parse
--abbrev-ref HEAD for the current branch, and injects the combined
string as the CROSSPOINT_VERSION preprocessor define. In a detached HEAD
state it falls back to the short commit SHA. If git is unavailable it
warns and falls back to unknown.

The script can also be run directly with python scripts/git_branch.py
for validation without triggering a full build.

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**< YES | PARTIALLY | NO
>**_

authored by

jpirnay and committed by
GitHub
3da2cd3c 88c49b8b

+85 -1
+2 -1
platformio.ini
··· 46 46 extra_scripts = 47 47 pre:scripts/build_html.py 48 48 pre:scripts/gen_i18n.py 49 + pre:scripts/git_branch.py 49 50 50 51 ; Libraries 51 52 lib_deps = ··· 62 63 extends = base 63 64 build_flags = 64 65 ${base.build_flags} 65 - -DCROSSPOINT_VERSION=\"${crosspoint.version}-dev\" 66 + ; CROSSPOINT_VERSION is set by scripts/git_branch.py (includes current branch) 66 67 -DENABLE_SERIAL_LOG 67 68 -DLOG_LEVEL=2 ; Set log level to debug for development builds 68 69
+83
scripts/git_branch.py
··· 1 + """ 2 + PlatformIO pre-build script: inject git branch into CROSSPOINT_VERSION for 3 + the default (dev) environment. 4 + 5 + Results in a version string like: 1.1.0-dev+feat-koysnc-xpath 6 + Release environments are unaffected; they set CROSSPOINT_VERSION in the ini. 7 + """ 8 + 9 + import configparser 10 + import os 11 + import subprocess 12 + import sys 13 + 14 + 15 + def warn(msg): 16 + print(f'WARNING [git_branch.py]: {msg}', file=sys.stderr) 17 + 18 + 19 + def get_git_branch(project_dir): 20 + try: 21 + branch = subprocess.check_output( 22 + ['git', 'rev-parse', '--abbrev-ref', 'HEAD'], 23 + text=True, stderr=subprocess.PIPE, cwd=project_dir 24 + ).strip() 25 + # Detached HEAD — show the short SHA instead 26 + if branch == 'HEAD': 27 + branch = subprocess.check_output( 28 + ['git', 'rev-parse', '--short', 'HEAD'], 29 + text=True, stderr=subprocess.PIPE, cwd=project_dir 30 + ).strip() 31 + # Strip characters that would break a C string literal 32 + return ''.join(c for c in branch if c not in '"\\') 33 + except FileNotFoundError: 34 + warn('git not found on PATH; branch suffix will be "unknown"') 35 + return 'unknown' 36 + except subprocess.CalledProcessError as e: 37 + warn(f'git command failed (exit {e.returncode}): {e.stderr.strip()}; branch suffix will be "unknown"') 38 + return 'unknown' 39 + except Exception as e: 40 + warn(f'Unexpected error reading git branch: {e}; branch suffix will be "unknown"') 41 + return 'unknown' 42 + 43 + 44 + def get_base_version(project_dir): 45 + ini_path = os.path.join(project_dir, 'platformio.ini') 46 + if not os.path.isfile(ini_path): 47 + warn(f'platformio.ini not found at {ini_path}; base version will be "0.0.0"') 48 + return '0.0.0' 49 + config = configparser.ConfigParser() 50 + config.read(ini_path) 51 + if not config.has_option('crosspoint', 'version'): 52 + warn('No [crosspoint] version in platformio.ini; base version will be "0.0.0"') 53 + return '0.0.0' 54 + return config.get('crosspoint', 'version') 55 + 56 + 57 + def inject_version(env): 58 + # Only applies to the dev (default) environment; release envs set the 59 + # version via build_flags in platformio.ini and are unaffected. 60 + if env['PIOENV'] != 'default': 61 + return 62 + 63 + project_dir = env['PROJECT_DIR'] 64 + base_version = get_base_version(project_dir) 65 + branch = get_git_branch(project_dir) 66 + version_string = f'{base_version}-dev+{branch}' 67 + 68 + env.Append(CPPDEFINES=[('CROSSPOINT_VERSION', f'\\"{version_string}\\"')]) 69 + print(f'CrossPoint build version: {version_string}') 70 + 71 + 72 + # PlatformIO/SCons entry point — Import and env are SCons builtins injected at runtime. 73 + # When run directly with Python (e.g. for validation), a lightweight fake env is used 74 + # so the git/version logic can be exercised without a full build. 75 + try: 76 + Import('env') # noqa: F821 # type: ignore[name-defined] 77 + inject_version(env) # noqa: F821 # type: ignore[name-defined] 78 + except NameError: 79 + class _Env(dict): 80 + def Append(self, **_): pass 81 + 82 + _project_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 83 + inject_version(_Env({'PIOENV': 'default', 'PROJECT_DIR': _project_dir}))