diff --git a/.pkgr.yml b/.pkgr.yml
index 1a59baffe6..ef91326b82 100644
--- a/.pkgr.yml
+++ b/.pkgr.yml
@@ -15,6 +15,8 @@ env:
- INVENTREE_PLUGIN_FILE=/opt/inventree/plugins.txt
- INVENTREE_CONFIG_FILE=/opt/inventree/config.yaml
after_install: contrib/packager.io/postinstall.sh
+before:
+ - contrib/packager.io/before.sh
dependencies:
- curl
- python3
diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py
index d5faf1fbbe..7ea7eb06af 100644
--- a/InvenTree/InvenTree/settings.py
+++ b/InvenTree/InvenTree/settings.py
@@ -22,6 +22,7 @@ from django.http import Http404
from django.utils.translation import gettext_lazy as _
import moneyed
+from dotenv import load_dotenv
from InvenTree.config import get_boolean_setting, get_custom_file, get_setting
from InvenTree.sentry import default_sentry_dsn, init_sentry
@@ -65,6 +66,12 @@ BASE_DIR = config.get_base_dir()
# Load configuration data
CONFIG = config.load_config_data(set_cache=True)
+# Load VERSION data if it exists
+version_file = BASE_DIR.parent.joinpath('VERSION')
+if version_file.exists():
+ print('load version from file')
+ load_dotenv(version_file)
+
# Default action is to run the system in Debug mode
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = get_boolean_setting('INVENTREE_DEBUG', 'debug', True)
diff --git a/InvenTree/InvenTree/version.py b/InvenTree/InvenTree/version.py
index 8289882be3..8735a8253c 100644
--- a/InvenTree/InvenTree/version.py
+++ b/InvenTree/InvenTree/version.py
@@ -5,11 +5,13 @@ Provides information on the current InvenTree version
import os
import pathlib
+import platform
import re
from datetime import datetime as dt
from datetime import timedelta as td
import django
+from django.conf import settings
from dulwich.repo import NotGitRepository, Repo
@@ -130,3 +132,48 @@ def inventreeCommitDate():
commit_dt = dt.fromtimestamp(main_commit.commit_time) + td(seconds=main_commit.commit_timezone)
return str(commit_dt.date())
+
+
+def inventreeInstaller():
+ """Returns the installer for the running codebase - if set."""
+ # First look in the environment variables, e.g. if running in docker
+
+ installer = os.environ.get('INVENTREE_PKG_INSTALLER', '')
+
+ if installer:
+ return installer
+ elif settings.DOCKER:
+ return 'DOC'
+ elif main_commit is not None:
+ return 'GIT'
+
+ return None
+
+
+def inventreeBranch():
+ """Returns the branch for the running codebase - if set."""
+ # First look in the environment variables, e.g. if running in docker
+
+ branch = os.environ.get('INVENTREE_PKG_BRANCH', '')
+
+ if branch:
+ return branch
+
+ if main_commit is None:
+ return None
+
+ branch = main_repo.refs.follow(b'HEAD')[0][1].decode()
+ return branch.removeprefix('refs/heads/')
+
+
+def inventreeTarget():
+ """Returns the target platform for the running codebase - if set."""
+ # First look in the environment variables, e.g. if running in docker
+
+ return os.environ.get('INVENTREE_PKG_TARGET', None)
+
+
+def inventreePlatform():
+ """Returns the platform for the instance."""
+
+ return platform.platform(aliased=True)
diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py
index a2d0e42648..8c2fe6f084 100644
--- a/InvenTree/part/templatetags/inventree_extras.py
+++ b/InvenTree/part/templatetags/inventree_extras.py
@@ -287,6 +287,30 @@ def inventree_commit_date(*args, **kwargs):
return version.inventreeCommitDate()
+@register.simple_tag()
+def inventree_installer(*args, **kwargs):
+ """Return InvenTree package installer string."""
+ return version.inventreeInstaller()
+
+
+@register.simple_tag()
+def inventree_branch(*args, **kwargs):
+ """Return InvenTree git branch string."""
+ return version.inventreeBranch()
+
+
+@register.simple_tag()
+def inventree_target(*args, **kwargs):
+ """Return InvenTree target string."""
+ return version.inventreeTarget()
+
+
+@register.simple_tag()
+def inventree_platform(*args, **kwargs):
+ """Return InvenTree platform string."""
+ return version.inventreePlatform()
+
+
@register.simple_tag()
def inventree_github_url(*args, **kwargs):
"""Return URL for InvenTree github site."""
diff --git a/InvenTree/templates/about.html b/InvenTree/templates/about.html
index ddd73ac9b5..0c02ade0e1 100644
--- a/InvenTree/templates/about.html
+++ b/InvenTree/templates/about.html
@@ -36,6 +36,13 @@
{% trans "Commit Date" %} | {% render_date commit_date %}{% include "clip.html" %} |
{% endif %}
+ {% inventree_branch as branch %}
+ {% if branch %}
+
+ |
+ {% trans "Commit Branch" %} | {{ branch }}{% include "clip.html" %} |
+
+ {% endif %}
{% endif %}
|
diff --git a/InvenTree/templates/version.html b/InvenTree/templates/version.html
index 5c0fa0142b..2dfd7abcb4 100644
--- a/InvenTree/templates/version.html
+++ b/InvenTree/templates/version.html
@@ -3,7 +3,11 @@ InvenTree-Version: {% inventree_version %}
Django Version: {% django_version %}
{% inventree_commit_hash as hash %}{% if hash %}Commit Hash: {{ hash }}{% endif %}
{% inventree_commit_date as commit_date %}{% if commit_date %}Commit Date: {% render_date commit_date %}{% endif %}
+{% inventree_branch as branch %}{% if branch %}Commit Branch: {{ branch }}{% endif %}
Database: {% inventree_db_engine %}
Debug-Mode: {% inventree_in_debug_mode %}
Deployed using Docker: {% inventree_docker_mode %}
+Platform: {% inventree_platform %}
+Installer: {% inventree_installer %}
+{% inventree_target as target %}{% if target %}Target: {{ target }}{% endif %}
Active plugins: {% plugins_info %}
diff --git a/contrib/packager.io/before.sh b/contrib/packager.io/before.sh
new file mode 100755
index 0000000000..b0bb808cef
--- /dev/null
+++ b/contrib/packager.io/before.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+#
+# packager.io before script
+#
+
+set -eu
+
+VERSION="$APP_PKG_VERSION-$APP_PKG_ITERATION"
+echo "Setting VERSION information to $VERSION"
+echo "$VERSION" > VERSION
+
+# The sha is the second element in APP_PKG_ITERATION
+SHA=$(echo $APP_PKG_ITERATION | cut -d'.' -f2)
+
+# Download info
+echo "Getting info from github for commit $SHA"
+curl -L \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ https://api.github.com/repos/InvenTree/InvenTree/commits/$SHA > commit.json
+curl -L \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ https://api.github.com/repos/InvenTree/InvenTree/commits/$SHA/branches-where-head > branches.json
+
+# Extract info
+echo "Extracting info from github"
+DATE=$(jq -r '.commit.committer.date' commit.json)
+BRANCH=$(jq -r '.[].name' branches.json)
+NODE_ID=$(jq -r '.node_id' commit.json)
+SIGNATURE=$(jq -r '.commit.verification.signature' commit.json)
+
+echo "Write VERSION information"
+echo "INVENTREE_COMMIT_HASH='$SHA'" >> VERSION
+echo "INVENTREE_COMMIT_DATE='$DATE'" >> VERSION
+echo "INVENTREE_PKG_INSTALLER='PKG'" >> VERSION
+echo "INVENTREE_PKG_BRANCH='$BRANCH'" >> VERSION
+echo "INVENTREE_PKG_TARGET='$TARGET'" >> VERSION
+echo "NODE_ID='$NODE_ID'" >> VERSION
+echo "SIGNATURE='$SIGNATURE'" >> VERSION
+
+echo "Written VERSION information"
+cat VERSION
diff --git a/docs/docs/start/advanced.md b/docs/docs/start/advanced.md
new file mode 100644
index 0000000000..5d240f51e4
--- /dev/null
+++ b/docs/docs/start/advanced.md
@@ -0,0 +1,39 @@
+---
+title: Advanced Topics
+---
+
+## Version Information
+
+Starting with version 0.12 (and later), InvenTree includes more version information.
+
+To view this information, navigate to the "About" page in the top menu bar and select "copy version information" on the bottom corner.
+
+### Contained Information
+
+The version information contains the following information extracted form the instance:
+
+| Name | Always | Sample | Source |
+| --- | --- | --- | --- |
+| InvenTree-Version | Yes | 0.12.0 dev | instance |
+| Django Version | Yes | 3.2.19 | instance |
+| Commit Hash | No | aebff26 | environment: `INVENTREE_COMMIT_HASH`, git |
+| Commit Date | No | 2023-06-10 | environment: `INVENTREE_COMMIT_DATE`, git |
+| Commit Branch | No | master | environment: `INVENTREE_PKG_BRANCH`, git |
+| Database | Yes | postgresql | environment: `INVENTREE_DB_*`, config: `database` - see [config](./config.md#database-options) |
+| Debug-Mode | Yes | False | environment: `INVENTREE_DEBUG`, config: `config` - see [config](./config.md#basic-options) |
+| Deployed using Docker | Yes | True | environment: `INVENTREE_DOCKER` |
+| Platform | Yes | Linux-5.15.0-67-generic-x86_64 | instance |
+| Installer | Yes | PKG | environment: `INVENTREE_PKG_INSTALLER`, instance |
+| Target | No | ubuntu:20.04 | environment: `INVENTREE_PKG_TARGET` |
+| Active plugins | Yes | [{'name': 'InvenTreeBarcode', 'slug': 'inventreebarcode', 'version': '2.0.0'}] | instance |
+
+
+### Installer codes
+
+The installer code is used to identify the way InvenTree was installed. If you vendor InvenTree, you can and should set the installer code to your own value to make sure debugging goes smoothly.
+
+| Code | Description | Official |
+| --- | --- | --- |
+| PKG | Installed using a package manager | Yes |
+| GIT | Installed using git | Yes |
+| DOC | Installed using docker | Yes |
diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml
index ac3361b7bd..46652d3306 100644
--- a/docs/mkdocs.yml
+++ b/docs/mkdocs.yml
@@ -94,6 +94,7 @@ nav:
- Serving Files: start/serving_files.md
- Data Backup: start/backup.md
- Migrating Data: start/migrate.md
+ - Advanced Topics: start/advanced.md
- Parts:
- Parts: part/part.md
- Creating Parts: part/create.md
diff --git a/requirements.in b/requirements.in
index cd01969dc5..cd5b876d87 100644
--- a/requirements.in
+++ b/requirements.in
@@ -36,6 +36,7 @@ pdf2image # PDF to image conversion
pillow # Image manipulation
pint==0.21 # Unit conversion # FIXED 2023-05-30 breaks tests https://github.com/matmair/InvenTree/actions/runs/5095665936/jobs/9160852560
python-barcode[images] # Barcode generator
+python-dotenv # Environment variable management
qrcode[pil] # QR code generator
rapidfuzz==0.7.6 # Fuzzy string matching
regex # Advanced regular expressions
diff --git a/requirements.txt b/requirements.txt
index 487dcfeadf..e7eebeac0d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -213,6 +213,8 @@ python-dateutil==2.8.2
# arrow
# django-recurrence
# icalendar
+python-dotenv==1.0.0
+ # via -r requirements.in
python-fsutil==0.10.0
# via django-maintenance-mode
python3-openid==3.2.0