33Use Docker container to build a Debian package.
44Using Docker approach to ensure a consistent and isolated build environment.
55
6- Requirement: The `toml` Python package
6+ Requirement:
7+ - toml
8+ - Docker
9+
10+ To install the required Python packages, run:
711
812 pip install toml
913
14+ To install Docker, follow the instructions at:
15+ https://docs.docker.com/get-docker/
16+
1017To run the script:
1118
1219 python build_deb_docker.py
1320
14- This script will generate the Debian package files and place them in the
15- dist/debian/ directory.
21+ This script will generate the Debian package files and the python wheel and
22+ place them in the dist/debian/ directory.
1623
17- Once the debian package is generated, you can install it using:
24+ Once the debian package is generated, one can install it using:
1825
1926 sudo apt install ./<package>.deb
2027
2128Note: The ./ is important - it tells apt to install from a local file
2229rather than searching repositories.
2330Replace the above path with the actual path to the generated debian file.
31+
32+ Run the binary directly
33+
34+ dejacode
2435"""
2536
2637import os
@@ -44,6 +55,15 @@ def build_deb_with_docker():
4455 # Debian version conventions replace hyphens with tildes
4556 deb_version = project ["version" ].replace ("-dev" , "~dev" )
4657
58+ # Get all dependencies
59+ dependencies = project .get ("dependencies" , [])
60+
61+ filtered_dependencies = [
62+ dep
63+ for dep in dependencies
64+ if "django-rest-hooks" not in dep and "django_notifications_patched" not in dep
65+ ]
66+
4767 docker_cmd = [
4868 "docker" ,
4969 "run" ,
@@ -52,38 +72,86 @@ def build_deb_with_docker():
5272 f"{ os .getcwd ()} :/workspace" ,
5373 "-w" ,
5474 "/workspace" ,
55- "ubuntu:22 .04" ,
75+ "ubuntu:24 .04" ,
5676 "/bin/bash" ,
5777 "-c" ,
5878 f"""set -ex
5979 # Install build dependencies
6080 apt-get update
61- apt-get install -y python3-dev python3-pip python3-venv debhelper dh-python devscripts
81+ apt-get install -y debhelper dh-python devscripts build-essential \
82+ libsasl2-dev libldap2-dev libssl-dev libpq-dev
83+
84+ # Install Python 3.13 from deadsnakes PPA
85+ apt-get install -y software-properties-common
86+ add-apt-repository -y ppa:deadsnakes/ppa
87+ apt-get update
88+ apt-get install -y python3.13 python3.13-dev python3.13-venv
89+
90+ # Create and activate virtual environment with Python 3.13 using --copies
91+ python3.13 -m venv /opt/{ deb_name } --copies
92+ . /opt/{ deb_name } /bin/activate
93+
94+ # Upgrade pip to latest version and ensure setuptools is available
95+ pip install --upgrade pip setuptools wheel
96+
97+ # Clean previous build artifacts
98+ rm -rf build/
99+
100+ # Install non-PyPI dependencies
101+ pip install https://github.com/aboutcode-org/django-rest-hooks/releases/download/1.6.1/django_rest_hooks-1.6.1-py2.py3-none-any.whl
102+ pip install https://github.com/dejacode/django-notifications-patched/archive/refs/tags/2.0.0.tar.gz
103+
104+ # Install dependencies directly
105+ { " && " .join ([f'pip install "{ dep } "' for dep in filtered_dependencies ])}
62106
63107 # Install build tool
64108 pip install build
65109
66110 # Build the wheel
67- python3 -m build --wheel
68-
69- # Move wheel to dist/debian/
70- mkdir -p dist/debian
71- mv dist/*.whl dist/debian/
72-
73- # Get the wheel file name
74- WHEEL_FILE=$(ls dist/debian/*.whl)
75- if [ -z "$WHEEL_FILE" ]; then
76- echo "Error: No wheel file found in dist/debian/." >&2
77- exit 1
78- fi
111+ python3.13 -m build --wheel
112+
113+ # Install the package and all remaining dependencies
114+ WHEEL_FILE=$(ls dist/*.whl)
115+
116+ # Install the main package
117+ pip install "$WHEEL_FILE"
118+
119+ # Copy source code to /opt/{ deb_name } /src
120+ mkdir -p /opt/{ deb_name } /src
121+ cp -r /workspace/* /opt/{ deb_name } /src/ 2>/dev/null || true
122+ rm -rf /opt/{ deb_name } /src/dist /opt/{ deb_name } /src/build 2>/dev/null || true
123+
124+ # Fix shebangs in the virtual environment to use absolute paths
125+ for script in /opt/{ deb_name } /bin/*; do
126+ if [ -f "$script" ] && head -1 "$script" | grep -q "^#!"; then
127+ # Use sed to safely replace only the first line with absolute path
128+ sed -i '1s|.*|#!/opt/{ deb_name } /bin/python3|' "$script"
129+ fi
130+ done
131+
132+ # Remove pip and wheel to reduce package size
133+ rm -f /opt/{ deb_name } /bin/pip* /opt/{ deb_name } /bin/wheel
134+
135+ # Ensure all scripts are executable
136+ chmod -R 755 /opt/{ deb_name } /bin/
137+
138+ # Create wrapper script (like in RPM) instead of direct symlink
139+ cat > /opt/{ deb_name } /bin/dejacode-wrapper << 'WRAPPER_EOF'
140+ #!/bin/bash
141+ export PYTHONPATH="/opt/{ deb_name } /src:/opt/{ deb_name } /lib/python3.13/site-packages"
142+ cd "/opt/{ deb_name } /src"
143+ exec "/opt/{ deb_name } /bin/dejacode" "$@"
144+ WRAPPER_EOF
145+ chmod 755 /opt/{ deb_name } /bin/dejacode-wrapper
79146
80147 # Create temporary directory for package building
81148 TEMP_DIR=$(mktemp -d)
82149 PKG_DIR="$TEMP_DIR/{ deb_name } -{ deb_version } "
83150 mkdir -p "$PKG_DIR"
84151
85- # Extract wheel contents to package directory
86- unzip "$WHEEL_FILE" -d "$PKG_DIR"
152+ # Copy the installed package files
153+ mkdir -p "$PKG_DIR/opt/"
154+ cp -r /opt/{ deb_name } "$PKG_DIR/opt/"
87155
88156 # Create DEBIAN control file
89157 mkdir -p "$PKG_DIR/DEBIAN"
@@ -98,14 +166,39 @@ def build_deb_with_docker():
98166 "Automate open source license compliance andensure supply chain integrity" ,
99167 )
100168 }
101- Depends: python3
169+ Depends: python3.13, git, libldap2 | libldap-2.5-0, libsasl2-2, libssl3 | libssl3t64, libpq5
102170Section: python
103171Priority: optional
104172Homepage: { project .get ("urls" , "" ).get ("Homepage" , "https://github.com/aboutcode-org/dejacode" )}
105173EOF
106174
175+ # Create postinst script to setup symlinks
176+ cat > "$PKG_DIR/DEBIAN/postinst" << 'POSTINST'
177+ #!/bin/bash
178+ # Create symlinks for binaries - use the wrapper script
179+ if [ -f "/opt/{ deb_name } /bin/dejacode-wrapper" ]; then
180+ ln -sf "/opt/{ deb_name } /bin/dejacode-wrapper" "/usr/local/bin/dejacode"
181+ fi
182+
183+ # Ensure proper permissions
184+ chmod -R 755 /opt/{ deb_name } /bin/
185+ POSTINST
186+ chmod 755 "$PKG_DIR/DEBIAN/postinst"
187+
188+ # Create prerm script to clean up symlinks
189+ cat > "$PKG_DIR/DEBIAN/prerm" << 'PRERM'
190+ #!/bin/bash
191+ # Remove symlinks
192+ rm -f "/usr/local/bin/dejacode"
193+ PRERM
194+ chmod 755 "$PKG_DIR/DEBIAN/prerm"
195+
107196 # Build the .deb package
108- dpkg-deb --build "$PKG_DIR" dist/debian/
197+ mkdir -p dist/debian
198+ dpkg-deb --build "$PKG_DIR" "dist/debian/{ deb_name } _{ deb_version } _all.deb"
199+
200+ # Move wheel to dist/debian/
201+ mv dist/*.whl dist/debian/
109202
110203 # Clean up
111204 rm -rf "$TEMP_DIR"
0 commit comments