Skip to content

Commit 4bb2a02

Browse files
committed
Update packaging script for Debian #341
Signed-off-by: Chin Yeung Li <[email protected]>
1 parent 6e66628 commit 4bb2a02

File tree

1 file changed

+115
-22
lines changed

1 file changed

+115
-22
lines changed

etc/scripts/build_deb_docker.py

Lines changed: 115 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,35 @@
33
Use Docker container to build a Debian package.
44
Using 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+
1017
To 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
2128
Note: The ./ is important - it tells apt to install from a local file
2229
rather than searching repositories.
2330
Replace the above path with the actual path to the generated debian file.
31+
32+
Run the binary directly
33+
34+
dejacode
2435
"""
2536

2637
import 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
102170
Section: python
103171
Priority: optional
104172
Homepage: {project.get("urls", "").get("Homepage", "https://github.com/aboutcode-org/dejacode")}
105173
EOF
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

Comments
 (0)