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
10 changes: 10 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.git
**/__pycache__
*.py[cod]
.pytest_cache
.mypy_cache
.coverage
htmlcov
dist
.venv
*.egg-info
83 changes: 83 additions & 0 deletions .github/workflows/publish-python.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Publish pytrustnfe3 to CodeArtifact

on:
workflow_call:
inputs:
version:
description: "Version (CalVer): YYYYMMDD.X — (e.g. 20260515.1)."
required: true
type: string
isSnapshot:
description: "If true (xproto-style): FINAL_VERSION=<base>-dev+<git short sha> with base CalVer."
required: true
type: boolean
default: false
workflow_dispatch:
inputs:
version:
description: "CalVer: YYYYMMDD.X (e.g. 20260515.1; avoid leading zeros after the dot)"
required: true
type: string
isSnapshot:
description: "Snapshot build: append -dev+<git short sha> to the CalVer base (same as xproto)."
required: true
type: boolean
default: false

jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_CODE_ARTIFACT }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_CODE_ARTIFACT }}
aws-region: ${{ secrets.AWS_REGION_CODE_ARTIFACT }}

- name: CodeArtifact authorization token
run: |
CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token \
--domain loggi \
--domain-owner ${{ secrets.AWS_DOMAIN_OWNER_CODE_ARTIFACT }} \
--region ${{ secrets.AWS_REGION_CODE_ARTIFACT }} \
--query authorizationToken --output text)
echo "::add-mask::$CODEARTIFACT_AUTH_TOKEN"
echo "CODEARTIFACT_AUTH_TOKEN=$CODEARTIFACT_AUTH_TOKEN" >> "$GITHUB_ENV"

- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.8"

- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: 1.8.5
virtualenvs-create: true
virtualenvs-in-project: true

- name: Install dependencies
run: poetry install --with dev --no-interaction --no-root

- name: Compose version string
run: |
set -euo pipefail
if [ "${{ inputs.isSnapshot }}" = "true" ]; then
echo "FINAL_VERSION=${BASE}-dev+$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
else
echo "FINAL_VERSION=${BASE}" >> "$GITHUB_ENV"
fi
env:
BASE: ${{ inputs.version }}

- name: Publish to CodeArtifact
env:
POETRY_HTTP_BASIC_LOGGI_USERNAME: aws
POETRY_HTTP_BASIC_LOGGI_PASSWORD: ${{ env.CODEARTIFACT_AUTH_TOKEN }}
FINAL_VERSION: ${{ env.FINAL_VERSION }}
run: |
poetry version "$FINAL_VERSION"
poetry publish --build --repository loggi
79 changes: 79 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Tests

on:
push:
branches:
- master
- main
pull_request:
types: [opened, synchronize, reopened]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
test:
name: pytest
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v5

- name: Install OS dependencies (libxml2 / xmlsec stack)
run: |
sudo apt-get update -y
sudo apt-get install -y --no-install-recommends \
ca-certificates \
libxml2 libxslt1.1 libxmlsec1 libxmlsec1-openssl openssl \
libxml2-dev libxslt1-dev libxmlsec1-dev \
zlib1g-dev pkg-config build-essential

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.8"

- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: 1.8.5
virtualenvs-create: true
virtualenvs-in-project: true
installer-parallel: true

- name: Install dependencies
run: poetry install --no-interaction --with dev

# Align lxml/xmlsec with system libxml2 (same strategy as Dockerfile).
- name: Rebuild lxml and xmlsec against system libraries
run: |
poetry run python - <<'PY'
import subprocess
import sys

from pkg_resources import get_distribution

lv = get_distribution("lxml").version
xv = get_distribution("xmlsec").version
subprocess.check_call(
[
sys.executable,
"-m",
"pip",
"install",
"--no-cache-dir",
"--force-reinstall",
"--no-binary=lxml",
"--no-binary=xmlsec",
f"lxml=={lv}",
f"xmlsec=={xv}",
]
)
PY

- name: Run tests
run: poetry run pytest -q --cov=pytrustnfe --cov-report=term-missing
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ sent_xml.xml
received_xml.xml
nfse-exemplo.py
.idea

.coverage
.coverage.*
21 changes: 0 additions & 21 deletions .travis.yml

This file was deleted.

52 changes: 52 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Python 3.8 / Debian bookworm — lxml+xmlsec são recompiladas contra libs do sistema (mais estável que wheel misto na PyPI).
FROM python:3.8-slim-bookworm

ENV POETRY_VERSION=1.8.5 \
POETRY_NO_INTERACTION=1 \
POETRY_VIRTUALENVS_IN_PROJECT=false \
PIP_DISABLE_PIP_VERSION_CHECK=1

# Runtime + headers so lxml+xmlsec rebuild against the same system libxml2/libxmlsec1 (manylinux wheels can still mismatch).
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates curl \
libxml2 libxslt1.1 libxmlsec1 libxmlsec1-openssl openssl \
libxml2-dev libxslt1-dev libxmlsec1-dev \
zlib1g-dev pkg-config build-essential \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /workspace

COPY pyproject.toml poetry.lock poetry.toml README.md /workspace/
COPY pytrustnfe /workspace/pytrustnfe
COPY tests /workspace/tests

RUN pip install "poetry==${POETRY_VERSION}" \
&& poetry install --with dev \
&& poetry run python - <<'PY'
import subprocess
import sys

from pkg_resources import get_distribution

lv = get_distribution("lxml").version
xv = get_distribution("xmlsec").version
subprocess.check_call(
[
sys.executable,
"-m",
"pip",
"install",
"--no-cache-dir",
"--force-reinstall",
"--no-binary=lxml",
"--no-binary=xmlsec",
f"lxml=={lv}",
f"xmlsec=={xv}",
]
)
PY

RUN poetry run python -c "import lxml, xmlsec; print('xml stack ok', lxml.__version__)" \
&& poetry run pytest -q --tb=no

CMD ["poetry", "run", "pytest", "-q"]
51 changes: 51 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
IMAGE ?= pytrustnfe-build

AWS_PROFILE ?= platform-prod-sso

CODEARTIFACT_DOMAIN ?= loggi
CODEARTIFACT_DOMAIN_OWNER ?= 550903664601
CODEARTIFACT_REGION ?= us-east-1

.PHONY: build test shell dist wheel publish-release publish-ca publish-ca-build aws-sso

build:
docker build -t $(IMAGE) .

test:
docker run --rm $(IMAGE) poetry run pytest -q

shell:
docker run --rm -it $(IMAGE) bash -il

# Build wheel + sdist inside the image and copy both into ./dist
dist:
@mkdir -p dist
docker run --rm -v "$(CURDIR)/dist:/out" $(IMAGE) sh -eu -c "\
poetry build && cp dist/pytrustnfe3-*.whl /out/ && cp dist/pytrustnfe3-*.tar.gz /out/"

# Alias kept for callers that only cared about wheels.
wheel: dist

aws-sso:
aws sso login --profile $(AWS_PROFILE)

# Set CalVer in pyproject, then CodeArtifact publish (build+wheels). Usage: make publish-release VERSION=20260515.2
publish-release:
@test -n "$(VERSION)" || (echo "usage: make publish-release VERSION=YYYYMMDD.XX" >&2; exit 1)
poetry version "$(VERSION)"
$(MAKE) publish-ca-build

# Publish ./dist/* to AWS CodeArtifact (build first: `make dist` or pass --build targets below).
publish-ca:
AWS_PROFILE="$(AWS_PROFILE)" \
CODEARTIFACT_DOMAIN="$(CODEARTIFACT_DOMAIN)" \
CODEARTIFACT_DOMAIN_OWNER="$(CODEARTIFACT_DOMAIN_OWNER)" \
CODEARTIFACT_REGION="$(CODEARTIFACT_REGION)" \
bash "$(CURDIR)/ops/publish-codeartifact.sh"

publish-ca-build:
AWS_PROFILE="$(AWS_PROFILE)" \
CODEARTIFACT_DOMAIN="$(CODEARTIFACT_DOMAIN)" \
CODEARTIFACT_DOMAIN_OWNER="$(CODEARTIFACT_DOMAIN_OWNER)" \
CODEARTIFACT_REGION="$(CODEARTIFACT_REGION)" \
bash "$(CURDIR)/ops/publish-codeartifact.sh" --build
Loading