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
54 changes: 54 additions & 0 deletions .github/actions/install-softhsm/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: install-softhsm
author: Matthias Valvekens
description: Install SoftHSM and configure an empty token
inputs:
os:
description: OS to target
required: true
token-label:
description: Label assigned to the token
required: false
default: TEST
token-user-pin:
description: User PIN to configure on the token
required: false
default: "1234"
token-so-pin:
description: Security officer PIN to configure on the token
required: false
default: "5678"
runs:
using: "composite"
steps:
- name: Install SoftHSM
shell: bash
run: |
if [[ "${OS_NAME:0:6}" == 'ubuntu' ]]; then
sudo apt-get install softhsm2
mkdir softhsm_tokens
echo "directories.tokendir = $(pwd)/softhsm_tokens" > /tmp/softhsm2.conf
echo "SOFTHSM2_CONF=/tmp/softhsm2.conf" >> "$GITHUB_ENV"
echo "PKCS11_MODULE=/usr/lib/softhsm/libsofthsm2.so" >> "$GITHUB_ENV"
elif [[ "${OS_NAME:0:5}" == 'macos' ]]; then
brew install softhsm
echo "PKCS11_MODULE=/opt/homebrew/lib/softhsm/libsofthsm2.so" >> "$GITHUB_ENV"
elif [[ "${OS_NAME:0:7}" == 'windows' ]]; then
choco install softhsm.install
echo "SOFTHSM2_CONF=D:/SoftHSM2/etc/softhsm2.conf" >> "$GITHUB_ENV"
echo "PKCS11_MODULE=D:/SoftHSM2/lib/softhsm2-x64.dll" >> "$GITHUB_ENV"
echo "D:/SoftHSM2/bin" >> "$GITHUB_PATH"
echo "D:/SoftHSM2/lib" >> "$GITHUB_PATH"
else
echo "$OS_NAME is not a supported target system"
exit 1
fi
env:
OS_NAME: ${{ inputs.os }}
- name: Initialize SoftHSM token
shell: bash
run: |
softhsm2-util --init-token --free --label "${{ inputs.token-label }}" \
--pin "${{ inputs.token-user-pin }}" --so-pin "${{ inputs.token-so-pin }}"
echo "PKCS11_TOKEN_LABEL=${{ inputs.token-label }}" >> "$GITHUB_ENV"
echo "PKCS11_TOKEN_PIN=${{ inputs.token-user-pin }}" >> "$GITHUB_ENV"
echo "PKCS11_TOKEN_SO_PIN=${{ inputs.token-so-pin }}" >> "$GITHUB_ENV"
1 change: 1 addition & 0 deletions .github/release-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A source distribution and wheels for common platforms have been published to [PyPI](https://pypi.org/project/python-pkcs11/:VERSION).
12 changes: 7 additions & 5 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
name: Code quality
on:
push:
push: {}
pull_request: {}
env:
UV_PYTHON_PREFERENCE: only-system
UV_NO_SYNC: "1"
jobs:
run:
runs-on: ubuntu-latest
steps:
- name: Acquire sources
uses: actions/checkout@v4.1.1
uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true

- name: Setup Python
uses: actions/setup-python@v5.0.0
uses: actions/setup-python@v5
with:
python-version: "3.13"
architecture: x64

- name: Install dev dependencies
run: uv sync
- name: Install lint dependencies
run: uv sync --no-dev --exact --group lint

- name: ruff format
run: uv run ruff format --diff .
Expand Down
141 changes: 132 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,141 @@ on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'

workflow_dispatch:
inputs:
environment:
type: environment
description: "Environment in which to execute the release process"
env:
UV_PYTHON_PREFERENCE: only-system
# we do all UV syncing explicitly
UV_NO_SYNC: "1"
jobs:
pypi-publish:
name: Build and upload release to PyPI
extract-params:
name: Determine release parameters
runs-on: ubuntu-latest
permissions: {}
outputs:
publish-env: ${{ steps.setenv.outputs.envname }}
version: ${{ steps.getrelease.outputs.version }}
steps:
- id: setenv
run: |
if [[ $GITHUB_EVENT_NAME == 'workflow_dispatch' ]]; then
echo "envname=${{ inputs.environment }}" >> "$GITHUB_OUTPUT"
elif [[ $GITHUB_EVENT_NAME == 'push' ]]; then
echo "envname=pypi" >> "$GITHUB_OUTPUT"
else
echo "Cannot run release workflow for trigger event $GITHUB_EVENT_NAME"
exit 1
fi
cat "$GITHUB_OUTPUT"
- name: Get version information
id: getrelease
run: |
set -eo pipefail

VER_REGEX="v[0-9]\+\.[0-9]\+\..\+"
if [[ "${GITHUB_REF:0:11}" != 'refs/tags/v' ]]; then
echo "Cannot run release workflow for ref $GITHUB_REF, must be a tag starting with 'v'"
exit 1
fi
VERSION=${GITHUB_REF:10}

if echo $VERSION | grep -q "$VER_REGEX"; then
echo "version=${VERSION:1}" >> "$GITHUB_OUTPUT"
else
echo "Tag $VERSION does not follow v<version> naming scheme"
exit 1
fi
- uses: actions/checkout@v4
- name: Generate release body
run: |
sed "s/:VERSION/$VERSION/g" < .github/release-template.md > release.md
cat release.md
env:
VERSION: ${{ steps.getrelease.outputs.version }}
- name: Upload release body
uses: actions/upload-artifact@v4
with:
name: release-body
path: release.md
build-wheels:
runs-on: ${{ matrix.os }}
needs: [extract-params]
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- ubuntu-24.04-arm
- windows-latest
- macos-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
- name: Build wheels
uses: pypa/[email protected]
- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl
build-sdist:
runs-on: ubuntu-latest
needs: [extract-params]
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: Build source distribution
run: uv build --sdist
- uses: actions/upload-artifact@v4
with:
name: sdist
path: ./dist/*.tar.gz
publish:
name: Publish release artifacts
needs: [extract-params, build-sdist, build-wheels]
runs-on: ubuntu-latest
environment: release
environment: ${{ needs.extract-params.outputs.publish-env }}
permissions:
# we use PyPI's trusted publisher model -> expose identity token
id-token: write
# Needed to create GitHub releases
contents: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- run: pip install build
- run: python -m build
- name: Publish package distributions to PyPI
- name: Download wheels
uses: actions/download-artifact@v4
with:
pattern: wheels-*
path: dist/
merge-multiple: 'true'
- name: Download source distribution
uses: actions/download-artifact@v4
with:
name: sdist
path: dist/
- name: Download release body
uses: actions/download-artifact@v4
with:
name: release-body
path: release-body
- name: Upload to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: ${{ vars.REPOSITORY_URL }}
- name: Create GitHub release
if: needs.extract-params.outputs.publish-env == 'pypi' && startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: |
dist/*.whl
dist/*.tar.gz
body_path: release-body/release.md
fail_on_unmatched_files: true
name: python-pkcs11 ${{ needs.extract-params.outputs.version }}
47 changes: 11 additions & 36 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
name: Tests
on:
push: {}
push:
branches: ["*"]
pull_request: {}
workflow_dispatch: {}
env:
UV_PYTHON_PREFERENCE: only-system
PKCS11_TOKEN_LABEL: TEST
PKCS11_TOKEN_PIN: 1234
PKCS11_TOKEN_SO_PIN: 5678
UV_NO_SYNC: "1"
jobs:
run:
runs-on: ${{ matrix.os }}
Expand All @@ -27,46 +27,21 @@ jobs:

steps:
- name: Acquire sources
uses: actions/checkout@v4.1.1
uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5.0.0
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Softhsm
shell: bash
run: |
if [[ $OS_NAME == 'ubuntu-latest' ]]; then
sudo apt-get install softhsm2
mkdir softhsm_tokens
echo "directories.tokendir = $(pwd)/softhsm_tokens" > /tmp/softhsm2.conf
echo "SOFTHSM2_CONF=/tmp/softhsm2.conf" >> "$GITHUB_ENV"
echo "PKCS11_MODULE=/usr/lib/softhsm/libsofthsm2.so" >> "$GITHUB_ENV"
elif [[ $OS_NAME == 'macos-latest' ]]; then
brew install softhsm
echo "PKCS11_MODULE=/opt/homebrew/lib/softhsm/libsofthsm2.so" >> "$GITHUB_ENV"
elif [[ $OS_NAME == 'windows-latest' ]]; then
choco install softhsm.install
echo "SOFTHSM2_CONF=D:/SoftHSM2/etc/softhsm2.conf" >> "$GITHUB_ENV"
echo "PKCS11_MODULE=D:/SoftHSM2/lib/softhsm2-x64.dll" >> "$GITHUB_ENV"
echo "D:/SoftHSM2/bin" >> "$GITHUB_PATH"
echo "D:/SoftHSM2/lib" >> "$GITHUB_PATH"
else
echo "$OS_NAME is not a supported target system"
exit 1
fi
env:
OS_NAME: ${{ matrix.os }}
- name: Initialize SoftHSM token
shell: bash
run: |
softhsm2-util --init-token --free --label $PKCS11_TOKEN_LABEL --pin $PKCS11_TOKEN_PIN --so-pin $PKCS11_TOKEN_SO_PIN
- uses: ./.github/actions/install-softhsm
Copy link
Collaborator Author

@MatthiasValvekens MatthiasValvekens Jun 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I extracted the SoftHSMv2 install logic to a separate file initially with the intention to use it for testing wheels during the build phase, but it appears that cibuildwheels uses containers to run its builds, so that didn't work out as planned. I left the install-softhsm action in place, though, since it keeps things a bit more readable.

with:
os: ${{ matrix.os }}
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
python-version: ${{ matrix.python-version }}
- name: Install dev dependencies
run: uv sync --all-extras
- name: Install testing dependencies
run: uv sync --no-dev --exact --group testing
- name: Run tests
run: uv run pytest -v
16 changes: 16 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: 2

build:
os: ubuntu-24.04
tools:
python: "3.12"
# readthedocs does not support [dependency-groups] directly
jobs:
create_environment:
- asdf plugin add uv
- asdf install uv latest
- asdf global uv latest
build:
html:
- make -C docs html BUILDDIR=$READTHEDOCS_OUTPUT
formats: all
8 changes: 4 additions & 4 deletions docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
#

# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = python -msphinx
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SPHINXPROJ = PythonPKCS11
SOURCEDIR = .
BUILDDIR = _build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@uv run --no-dev --group docs-build $(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@uv run --no-dev --group docs-build $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
Loading
Loading