Skip to content

Commit 98048d9

Browse files
Use uv to manage packages (#141)
* Refactor code structure for improved readability and maintainability * Add installation of Astral UV in CI workflow * Format installation instructions in README.md for better readability * Fix punctuation in README.md for uv documentation link * Refactor CI workflow and update Docker setup for mail-parser - Removed unnecessary debug steps and build arguments from GitHub Actions workflow. - Added detailed instructions for running the Docker image in README.md. - Replaced the old Dockerfile and docker-compose.yml with a new setup for improved functionality. * Remove Splunk app link from the README.md
1 parent 0c9259f commit 98048d9

20 files changed

Lines changed: 1645 additions & 325 deletions

.github/workflows/main.yml

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Python application and Docker image CI
22

33
on:
44
push:
5-
branches: [ master, develop ]
5+
branches: [ master, develop, feature/* ]
66
tags: [ '*.*.*' ] # Enable pipeline on tag pushes
77
pull_request:
88
branches: [ master, develop ]
@@ -12,7 +12,7 @@ jobs:
1212
runs-on: ubuntu-latest
1313
strategy:
1414
matrix:
15-
python-version: ['3.8', '3.9', '3.10']
15+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
1616

1717
steps:
1818
- uses: actions/checkout@v4
@@ -26,24 +26,24 @@ jobs:
2626

2727
- name: Install dependencies
2828
run: |
29+
curl -LsSf https://astral.sh/uv/install.sh | sh
2930
sudo apt-get -qq update
3031
sudo apt-get install -y libemail-outlook-message-perl
31-
pip install ".[dev, test]"
32+
uv sync
3233
export PERL_MM_USE_DEFAULT=1
3334
sudo cpan -f -i Email::Outlook::Message
3435
3536
- name: Run tests
3637
env:
3738
PYTHONPATH: src
3839
run: |
39-
pytest --cov=mailparser --cov-report=xml
40-
python -m mailparser -v
41-
python -m mailparser -h
42-
mail-parser -f tests/mails/mail_malformed_3 -j
43-
cat tests/mails/mail_malformed_3 | mail-parser -k -j
40+
make test
41+
uv run mail-parser -v
42+
uv run mail-parser -h
43+
uv run mail-parser -f tests/mails/mail_malformed_3 -j
44+
cat tests/mails/mail_malformed_3 | uv run mail-parser -k -j
4445
4546
- name: Run pre-commit
46-
if: matrix.python-version == '3.10'
4747
run: |
4848
make pre-commit
4949
@@ -56,7 +56,7 @@ jobs:
5656
- name: Build
5757
if: matrix.python-version == '3.10'
5858
run: |
59-
python -m build
59+
uv build
6060
6161
- name: Upload artifacts
6262
if: matrix.python-version == '3.10'
@@ -108,20 +108,15 @@ jobs:
108108
fi
109109
echo "REF_NAME=${REF_NAME,,}" >> $GITHUB_ENV
110110
111-
- name: Debug REF_NAME
112-
run: echo "REF_NAME=${{ env.REF_NAME }}"
113-
114111
- name: Build and push Docker image on GitHub Container Registry
115112
run: |
116-
cd docker
117113
IMAGE_NAME=ghcr.io/ghcr.io/spamscope/mail-parser/mailparser
118114
if [[ $GITHUB_REF == refs/tags/* ]]; then
119115
TAG=${GITHUB_REF#refs/tags/}
120116
docker build \
121117
--label "org.opencontainers.image.source=${{ github.repositoryUrl }}" \
122118
--label "org.opencontainers.image.description=Easy way to pass from raw mail to Python object" \
123119
--label "org.opencontainers.image.licenses=Apache-2.0" \
124-
--build-arg BRANCH=$TAG \
125120
-t $IMAGE_NAME:$TAG \
126121
-t $IMAGE_NAME:latest .
127122
docker push $IMAGE_NAME:$TAG
@@ -131,22 +126,19 @@ jobs:
131126
--label "org.opencontainers.image.source=${{ github.repositoryUrl }}" \
132127
--label "org.opencontainers.image.description=Easy way to pass from raw mail to Python object" \
133128
--label "org.opencontainers.image.licenses=Apache-2.0" \
134-
--build-arg BRANCH=${{ env.REF_NAME }} \
135129
-t $IMAGE_NAME:develop .
136130
docker push $IMAGE_NAME:develop
137131
fi
138132
139133
- name: Build and push Docker image on Docker Hub
140134
run: |
141-
cd docker
142135
IMAGE_NAME=docker.io/${{ secrets.DOCKER_USERNAME }}/spamscope-mail-parser
143136
if [[ $GITHUB_REF == refs/tags/* ]]; then
144137
TAG=${GITHUB_REF#refs/tags/}
145138
docker build \
146139
--label "org.opencontainers.image.source=${{ github.repositoryUrl }}" \
147140
--label "org.opencontainers.image.description=Easy way to pass from raw mail to Python object" \
148141
--label "org.opencontainers.image.licenses=Apache-2.0" \
149-
--build-arg BRANCH=$TAG \
150142
-t $IMAGE_NAME:$TAG \
151143
-t $IMAGE_NAME:latest .
152144
docker push $IMAGE_NAME:$TAG
@@ -156,7 +148,6 @@ jobs:
156148
--label "org.opencontainers.image.source=${{ github.repositoryUrl }}" \
157149
--label "org.opencontainers.image.description=Easy way to pass from raw mail to Python object" \
158150
--label "org.opencontainers.image.licenses=Apache-2.0" \
159-
--build-arg BRANCH=${{ env.REF_NAME }} \
160151
-t $IMAGE_NAME:develop .
161152
docker push $IMAGE_NAME:develop
162153
fi

Dockerfile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
FROM python:3.10-slim-bookworm
2+
3+
# Set environment variables
4+
5+
# Don’t buffer stdout/stderr, don’t write .pyc files
6+
ENV PYTHONUNBUFFERED=1
7+
ENV PYTHONDONTWRITEBYTECODE=1
8+
9+
ENV MAIL_PARSER_PATH=/app
10+
ENV BINARY_NAME="mail_parser-latest.tar.gz"
11+
12+
# Copy the mail-parser binary from the build context
13+
COPY ./dist/*.tar.gz ${MAIL_PARSER_PATH}/${BINARY_NAME}
14+
15+
# Install dependencies
16+
RUN apt-get -yqq update && \
17+
apt-get -yqq --no-install-recommends install libemail-outlook-message-perl && \
18+
apt-get clean && \
19+
rm -rf /var/lib/apt/lists/*
20+
21+
# Install the mail-parser package
22+
RUN useradd -m mailparser \
23+
&& chown mailparser:mailparser ${MAIL_PARSER_PATH} \
24+
&& pip install "${MAIL_PARSER_PATH}/${BINARY_NAME}"
25+
26+
USER mailparser
27+
28+
ENTRYPOINT ["mail-parser"]
29+
CMD ["-h"]

Makefile

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
1-
.PHONY: clean clean-test clean-pyc clean-build docs help
1+
.PHONY: help clean clean-build clean-test test lint format check install build release
22
.DEFAULT_GOAL := help
33

4-
define BROWSER_PYSCRIPT
5-
import os, webbrowser, sys
6-
7-
try:
8-
from urllib import pathname2url
9-
except:
10-
from urllib.request import pathname2url
11-
12-
webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1])))
13-
endef
14-
export BROWSER_PYSCRIPT
15-
164
define PRINT_HELP_PYSCRIPT
175
import re, sys
186

@@ -24,16 +12,18 @@ for line in sys.stdin:
2412
endef
2513
export PRINT_HELP_PYSCRIPT
2614

27-
BROWSER := python -c "$$BROWSER_PYSCRIPT"
15+
help: ## show this help message
16+
@python3 -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST)
2817

29-
help:
30-
@python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST)
18+
install: ## install dependencies using uv
19+
uv sync
3120

32-
clean-build: ## remove all build files
21+
clean-build: ## remove build artifacts
3322
find . -type d -name "build" -exec rm -rf {} +
3423
find . -type d -name "dist" -exec rm -rf {} +
24+
find . -type d -name "*.egg-info" -exec rm -rf {} +
3525

36-
clean-tests: ## remove test and coverage artifacts
26+
clean-test: ## remove test and coverage artifacts
3727
find . -type f -name "*.log" -delete
3828
find . -type f -name "coverage.xml" -delete
3929
find . -type f -name "junit.xml" -delete
@@ -43,16 +33,24 @@ clean-tests: ## remove test and coverage artifacts
4333
find . -type d -name ".mypy_cache" -exec rm -rf {} +
4434
find . -type d -name "__pycache__" -exec rm -rf {} +
4535

46-
clean-all: clean-tests clean-build ## remove all tests and build files
36+
clean: clean-test clean-build ## remove all artifacts
37+
38+
test: ## run tests
39+
uv run pytest
40+
41+
lint: ## run linting with ruff
42+
uv run ruff check .
43+
44+
format: ## format code with ruff
45+
uv run ruff format .
4746

48-
unittest: clean-tests ## run tests quickly with the default Python
49-
pytest
47+
check: lint test ## run linting and tests
5048

51-
pre-commit: ## run pre-commit on all files
52-
pre-commit run -a
49+
build: clean ## build package
50+
uv build
5351

54-
dist: clean-all ## builds source and wheel package
55-
python -m build
52+
pre-commit: ## run pre-commit hooks
53+
uv run pre-commit run --all-files
5654

57-
release: dist ## package and upload a release
58-
twine upload dist/*
55+
release: build ## build and upload to PyPI
56+
uv run twine upload dist/*

0 commit comments

Comments
 (0)