Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 10 additions & 19 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Python application and Docker image CI

on:
push:
branches: [ master, develop ]
branches: [ master, develop, feature/* ]
tags: [ '*.*.*' ] # Enable pipeline on tag pushes
pull_request:
branches: [ master, develop ]
Expand All @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']

steps:
- uses: actions/checkout@v4
Expand All @@ -26,24 +26,24 @@ jobs:

- name: Install dependencies
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
sudo apt-get -qq update
sudo apt-get install -y libemail-outlook-message-perl
pip install ".[dev, test]"
uv sync
export PERL_MM_USE_DEFAULT=1
sudo cpan -f -i Email::Outlook::Message

- name: Run tests
env:
PYTHONPATH: src
run: |
pytest --cov=mailparser --cov-report=xml
python -m mailparser -v
python -m mailparser -h
mail-parser -f tests/mails/mail_malformed_3 -j
cat tests/mails/mail_malformed_3 | mail-parser -k -j
make test
uv run mail-parser -v
uv run mail-parser -h
uv run mail-parser -f tests/mails/mail_malformed_3 -j
cat tests/mails/mail_malformed_3 | uv run mail-parser -k -j

- name: Run pre-commit
if: matrix.python-version == '3.10'
run: |
make pre-commit

Expand All @@ -56,7 +56,7 @@ jobs:
- name: Build
if: matrix.python-version == '3.10'
run: |
python -m build
uv build

- name: Upload artifacts
if: matrix.python-version == '3.10'
Expand Down Expand Up @@ -108,20 +108,15 @@ jobs:
fi
echo "REF_NAME=${REF_NAME,,}" >> $GITHUB_ENV

- name: Debug REF_NAME
run: echo "REF_NAME=${{ env.REF_NAME }}"

- name: Build and push Docker image on GitHub Container Registry
run: |
cd docker
IMAGE_NAME=ghcr.io/ghcr.io/spamscope/mail-parser/mailparser
if [[ $GITHUB_REF == refs/tags/* ]]; then
TAG=${GITHUB_REF#refs/tags/}
docker build \
--label "org.opencontainers.image.source=${{ github.repositoryUrl }}" \
--label "org.opencontainers.image.description=Easy way to pass from raw mail to Python object" \
--label "org.opencontainers.image.licenses=Apache-2.0" \
--build-arg BRANCH=$TAG \
-t $IMAGE_NAME:$TAG \
-t $IMAGE_NAME:latest .
docker push $IMAGE_NAME:$TAG
Expand All @@ -131,22 +126,19 @@ jobs:
--label "org.opencontainers.image.source=${{ github.repositoryUrl }}" \
--label "org.opencontainers.image.description=Easy way to pass from raw mail to Python object" \
--label "org.opencontainers.image.licenses=Apache-2.0" \
--build-arg BRANCH=${{ env.REF_NAME }} \
-t $IMAGE_NAME:develop .
docker push $IMAGE_NAME:develop
fi

- name: Build and push Docker image on Docker Hub
run: |
cd docker
IMAGE_NAME=docker.io/${{ secrets.DOCKER_USERNAME }}/spamscope-mail-parser
if [[ $GITHUB_REF == refs/tags/* ]]; then
TAG=${GITHUB_REF#refs/tags/}
docker build \
--label "org.opencontainers.image.source=${{ github.repositoryUrl }}" \
--label "org.opencontainers.image.description=Easy way to pass from raw mail to Python object" \
--label "org.opencontainers.image.licenses=Apache-2.0" \
--build-arg BRANCH=$TAG \
-t $IMAGE_NAME:$TAG \
-t $IMAGE_NAME:latest .
docker push $IMAGE_NAME:$TAG
Expand All @@ -156,7 +148,6 @@ jobs:
--label "org.opencontainers.image.source=${{ github.repositoryUrl }}" \
--label "org.opencontainers.image.description=Easy way to pass from raw mail to Python object" \
--label "org.opencontainers.image.licenses=Apache-2.0" \
--build-arg BRANCH=${{ env.REF_NAME }} \
-t $IMAGE_NAME:develop .
docker push $IMAGE_NAME:develop
fi
29 changes: 29 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM python:3.10-slim-bookworm

# Set environment variables

# Don’t buffer stdout/stderr, don’t write .pyc files
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1

ENV MAIL_PARSER_PATH=/app
ENV BINARY_NAME="mail_parser-latest.tar.gz"

# Copy the mail-parser binary from the build context
COPY ./dist/*.tar.gz ${MAIL_PARSER_PATH}/${BINARY_NAME}

# Install dependencies
RUN apt-get -yqq update && \
apt-get -yqq --no-install-recommends install libemail-outlook-message-perl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Install the mail-parser package
RUN useradd -m mailparser \
&& chown mailparser:mailparser ${MAIL_PARSER_PATH} \
&& pip install "${MAIL_PARSER_PATH}/${BINARY_NAME}"

USER mailparser

ENTRYPOINT ["mail-parser"]
CMD ["-h"]
52 changes: 25 additions & 27 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
.PHONY: clean clean-test clean-pyc clean-build docs help
.PHONY: help clean clean-build clean-test test lint format check install build release
.DEFAULT_GOAL := help

define BROWSER_PYSCRIPT
import os, webbrowser, sys

try:
from urllib import pathname2url
except:
from urllib.request import pathname2url

webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1])))
endef
export BROWSER_PYSCRIPT

define PRINT_HELP_PYSCRIPT
import re, sys

Expand All @@ -24,16 +12,18 @@ for line in sys.stdin:
endef
export PRINT_HELP_PYSCRIPT

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

help:
@python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST)
install: ## install dependencies using uv
uv sync

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

clean-tests: ## remove test and coverage artifacts
clean-test: ## remove test and coverage artifacts
find . -type f -name "*.log" -delete
find . -type f -name "coverage.xml" -delete
find . -type f -name "junit.xml" -delete
Expand All @@ -43,16 +33,24 @@ clean-tests: ## remove test and coverage artifacts
find . -type d -name ".mypy_cache" -exec rm -rf {} +
find . -type d -name "__pycache__" -exec rm -rf {} +

clean-all: clean-tests clean-build ## remove all tests and build files
clean: clean-test clean-build ## remove all artifacts

test: ## run tests
uv run pytest

lint: ## run linting with ruff
uv run ruff check .

format: ## format code with ruff
uv run ruff format .

unittest: clean-tests ## run tests quickly with the default Python
pytest
check: lint test ## run linting and tests

pre-commit: ## run pre-commit on all files
pre-commit run -a
build: clean ## build package
uv build

dist: clean-all ## builds source and wheel package
python -m build
pre-commit: ## run pre-commit hooks
uv run pre-commit run --all-files

release: dist ## package and upload a release
twine upload dist/*
release: build ## build and upload to PyPI
uv run twine upload dist/*
Loading