Repository: dynatrace-oss/dt-cli (language: python)

Issue:
Truly static binaries
Currently dtcli binaries depend on some arbitrary version on glibc, which we presume will be present on users system. It might not.

Ideas:
- https://github.com/pyinstaller/pyinstaller/wiki/FAQ#gnulinux



Discussion / hints:
I was wandering if we should rewrite dt-cli in Rust. Solves a lot of distribution related issues.
At some point, I was thinking we should rewrite it in TypeScript and leverage https://github.com/Dynatrace-ESA/dynatrace-api-client to build support to all APIs provided by Dynatrace as it was initially planned for DT, but turns out the new Extension SDK has a dependency on dt-cli so not sure if rewriting is an option. 

Fix patch:
diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index 258ccfb..c008241 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 1.6.9
+current_version = 1.6.10
 parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(-(?P<release>.*))?
 serialize = 
 	{major}.{minor}.{patch}-{release}
diff --git a/Dockerfile b/Dockerfile
index 76f73d7..ddad1c6 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,7 +2,7 @@ FROM python:3.9-slim
 
 # Install package build system
 RUN pip install poetry
-RUN apt-get update && apt-get install -y binutils
+RUN apt-get update && apt-get install -y binutils patchelf
 
 # Project directory must be mounted in /app
 WORKDIR /app
diff --git a/dtcli/version.py b/dtcli/version.py
index 62c4d78..793711a 100644
--- a/dtcli/version.py
+++ b/dtcli/version.py
@@ -12,4 +12,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-__version__ = "1.6.9"
+__version__ = "1.6.10"
diff --git a/poetry.lock b/poetry.lock
index eec8666..ba8dc76 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -650,6 +650,14 @@ snowballstemmer = "*"
 [package.extras]
 toml = ["toml"]
 
+[[package]]
+name = "pyelftools"
+version = "0.29"
+description = "Library for analyzing ELF files and DWARF debugging information"
+category = "dev"
+optional = false
+python-versions = "*"
+
 [[package]]
 name = "pyflakes"
 version = "2.3.1"
@@ -1002,6 +1010,17 @@ python-versions = ">=3.5"
 lint = ["flake8", "mypy", "docutils-stubs"]
 test = ["pytest"]
 
+[[package]]
+name = "staticx"
+version = "0.13.8"
+description = "Build static self-extracting app from dynamic executable"
+category = "dev"
+optional = false
+python-versions = ">=3.5"
+
+[package.dependencies]
+pyelftools = "*"
+
 [[package]]
 name = "toml"
 version = "0.10.2"
@@ -1090,7 +1109,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-
 [metadata]
 lock-version = "1.1"
 python-versions = "^3.8"
-content-hash = "d7cd24be22ed6138ed568325fdcb88454878478920c6a5616e02f66d32821d48"
+content-hash = "54072974fec800b939b467d3ad388581ef52cebc7f9377ddbfe2afd0c6cb6140"
 
 [metadata.files]
 alabaster = [
@@ -1349,6 +1368,10 @@ pydocstyle = [
     {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"},
     {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"},
 ]
+pyelftools = [
+    {file = "pyelftools-0.29-py2.py3-none-any.whl", hash = "sha256:519f38cf412f073b2d7393aa4682b0190fa901f7c3fa0bff2b82d537690c7fc1"},
+    {file = "pyelftools-0.29.tar.gz", hash = "sha256:ec761596aafa16e282a31de188737e5485552469ac63b60cfcccf22263fd24ff"},
+]
 pyflakes = [
     {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"},
     {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"},
@@ -1471,6 +1494,10 @@ sphinxcontrib-serializinghtml = [
     {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"},
     {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"},
 ]
+staticx = [
+    {file = "staticx-0.13.8-py3-none-manylinux1_x86_64.whl", hash = "sha256:b9f2ac9ad23dcf09099216a93d9c3c44e583a9b7959620a11f4d24a8f87d3c28"},
+    {file = "staticx-0.13.8.tar.gz", hash = "sha256:ed0104c907f760a7d459357402bcba10b52515fded71959536bb06302ff72f5b"},
+]
 toml = [
     {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
     {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
diff --git a/pyproject.toml b/pyproject.toml
index 25d3066..a5e3469 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -12,7 +12,7 @@ packages = [
 ]
 readme = "README.md"
 repository = "https://github.com/dynatrace-oss/dt-cli"
-version = "1.6.9"
+version = "1.6.10"
 
 
 [tool.poetry.dependencies]
@@ -49,6 +49,7 @@ pytest-mock = "^3.5"
 pytest-mypy = "^0.8"
 radon = "^4.0"
 sphinxcontrib-programoutput = "^0.17"
+staticx = "^0.13.8"
 
 [build-system]
 build-backend = "poetry.core.masonry.api"


Test patch:
diff --git a/.github/workflows/built-test-release.yml b/.github/workflows/built-test-release.yml
index 6927431..a998496 100644
--- a/.github/workflows/built-test-release.yml
+++ b/.github/workflows/built-test-release.yml
@@ -168,7 +168,7 @@ jobs:
 
       - name: Build package
         run: |
-          mkdir dist
+          mkdir -p dist
           docker run \
             -v $(pwd)/dist:/app/dist \
             docker.pkg.github.com/$GITHUB_REPOSITORY/dtcli-env:${GITHUB_SHA:0:6} \
@@ -194,7 +194,7 @@ jobs:
 
       - name: Build binary distribution
         run: |
-          mkdir dist
+          mkdir -p dist
           docker run \
             -v $(pwd)/dist:/app/dist \
             docker.pkg.github.com/$GITHUB_REPOSITORY/dtcli-env:${GITHUB_SHA:0:6} \
@@ -209,6 +209,23 @@ jobs:
         run: |
           ./dist/dt
 
+      - name: Make the binary static
+        run: |
+          docker run \
+            -v $(pwd)/dist:/app/dist \
+            docker.pkg.github.com/$GITHUB_REPOSITORY/dtcli-env:${GITHUB_SHA:0:6} \
+            poetry run staticx --strip dist/dt dist/dt-static
+
+          docker run \
+            -v $(pwd)/dist:/app/dist \
+            docker.pkg.github.com/$GITHUB_REPOSITORY/dtcli-env:${GITHUB_SHA:0:6} \
+            chown $(id -u):$(id -g) dist/dt-static
+
+      - name: Sanity
+        run: |
+          ./dist/dt-static
+          mv dist/dt-static dist/dt
+
       - name: Cache built linux binary artifact
         uses: actions/upload-artifact@v2
         with: