Skip to content

Commit d45957f

Browse files
Initial iteration of multiplatform release flow
- Upload both sdist and wheels - Reasonable selection of build targets - Integrate with GitHub releases - Manage released version based on git tag - Support multiple release environments - Move extension module setup into pyproject.toml It seems that the explicit linkage against user32.lib on Windows is no longer required. - Divide dependencies into groups Fixes #203.
1 parent e78ad1e commit d45957f

File tree

10 files changed

+311
-89
lines changed

10 files changed

+311
-89
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: install-softhsm
2+
author: Matthias Valvekens
3+
description: Install SoftHSM and configure an empty token
4+
inputs:
5+
os:
6+
description: OS to target
7+
required: true
8+
token-label:
9+
description: Label assigned to the token
10+
required: false
11+
default: TEST
12+
token-user-pin:
13+
description: User PIN to configure on the token
14+
required: false
15+
default: "1234"
16+
token-so-pin:
17+
description: Security officer PIN to configure on the token
18+
required: false
19+
default: "5678"
20+
runs:
21+
using: "composite"
22+
steps:
23+
- name: Install SoftHSM
24+
shell: bash
25+
run: |
26+
if [[ "${OS_NAME:0:6}" == 'ubuntu' ]]; then
27+
sudo apt-get install softhsm2
28+
mkdir softhsm_tokens
29+
echo "directories.tokendir = $(pwd)/softhsm_tokens" > /tmp/softhsm2.conf
30+
echo "SOFTHSM2_CONF=/tmp/softhsm2.conf" >> "$GITHUB_ENV"
31+
echo "PKCS11_MODULE=/usr/lib/softhsm/libsofthsm2.so" >> "$GITHUB_ENV"
32+
elif [[ "${OS_NAME:0:5}" == 'macos' ]]; then
33+
brew install softhsm
34+
echo "PKCS11_MODULE=/opt/homebrew/lib/softhsm/libsofthsm2.so" >> "$GITHUB_ENV"
35+
elif [[ "${OS_NAME:0:7}" == 'windows' ]]; then
36+
choco install softhsm.install
37+
echo "SOFTHSM2_CONF=D:/SoftHSM2/etc/softhsm2.conf" >> "$GITHUB_ENV"
38+
echo "PKCS11_MODULE=D:/SoftHSM2/lib/softhsm2-x64.dll" >> "$GITHUB_ENV"
39+
echo "D:/SoftHSM2/bin" >> "$GITHUB_PATH"
40+
echo "D:/SoftHSM2/lib" >> "$GITHUB_PATH"
41+
else
42+
echo "$OS_NAME is not a supported target system"
43+
exit 1
44+
fi
45+
env:
46+
OS_NAME: ${{ inputs.os }}
47+
- name: Initialize SoftHSM token
48+
shell: bash
49+
run: |
50+
softhsm2-util --init-token --free --label "${{ inputs.token-label }}" \
51+
--pin "${{ inputs.token-user-pin }}" --so-pin "${{ inputs.token-so-pin }}"
52+
echo "PKCS11_TOKEN_LABEL=${{ inputs.token-label }}" >> "$GITHUB_ENV"
53+
echo "PKCS11_TOKEN_PIN=${{ inputs.token-user-pin }}" >> "$GITHUB_ENV"
54+
echo "PKCS11_TOKEN_SO_PIN=${{ inputs.token-so-pin }}" >> "$GITHUB_ENV"

.github/release-template.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
A source distribution and wheels for common platforms have been published to [PyPI](https://pypi.org/project/python-pkcs11/:VERSION).

.github/workflows/quality.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
11
name: Code quality
22
on:
3-
push:
3+
push: {}
4+
pull_request: {}
45
env:
56
UV_PYTHON_PREFERENCE: only-system
7+
UV_NO_SYNC: "1"
68
jobs:
79
run:
810
runs-on: ubuntu-latest
911
steps:
1012
- name: Acquire sources
11-
uses: actions/checkout@v4.1.1
13+
uses: actions/checkout@v4
1214

1315
- name: Install uv
1416
uses: astral-sh/setup-uv@v4
1517
with:
1618
enable-cache: true
1719

1820
- name: Setup Python
19-
uses: actions/setup-python@v5.0.0
21+
uses: actions/setup-python@v5
2022
with:
2123
python-version: "3.13"
2224
architecture: x64
2325

24-
- name: Install dev dependencies
25-
run: uv sync
26+
- name: Install lint dependencies
27+
run: uv sync --no-dev --exact --group lint
2628

2729
- name: ruff format
2830
run: uv run ruff format --diff .

.github/workflows/release.yml

Lines changed: 132 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,141 @@ on:
44
push:
55
tags:
66
- 'v[0-9]+.[0-9]+.[0-9]+'
7-
7+
workflow_dispatch:
8+
inputs:
9+
environment:
10+
type: environment
11+
description: "Environment in which to execute the release process"
12+
env:
13+
UV_PYTHON_PREFERENCE: only-system
14+
# we do all UV syncing explicitly
15+
UV_NO_SYNC: "1"
816
jobs:
9-
pypi-publish:
10-
name: Build and upload release to PyPI
17+
extract-params:
18+
name: Determine release parameters
19+
runs-on: ubuntu-latest
20+
permissions: {}
21+
outputs:
22+
publish-env: ${{ steps.setenv.outputs.envname }}
23+
version: ${{ steps.getrelease.outputs.version }}
24+
steps:
25+
- id: setenv
26+
run: |
27+
if [[ $GITHUB_EVENT_NAME == 'workflow_dispatch' ]]; then
28+
echo "envname=${{ inputs.environment }}" >> "$GITHUB_OUTPUT"
29+
elif [[ $GITHUB_EVENT_NAME == 'push' ]]; then
30+
echo "envname=pypi" >> "$GITHUB_OUTPUT"
31+
else
32+
echo "Cannot run release workflow for trigger event $GITHUB_EVENT_NAME"
33+
exit 1
34+
fi
35+
cat "$GITHUB_OUTPUT"
36+
- name: Get version information
37+
id: getrelease
38+
run: |
39+
set -eo pipefail
40+
41+
VER_REGEX="v[0-9]\+\.[0-9]\+\..\+"
42+
if [[ "${GITHUB_REF:0:11}" != 'refs/tags/v' ]]; then
43+
echo "Cannot run release workflow for ref $GITHUB_REF, must be a tag starting with 'v'"
44+
exit 1
45+
fi
46+
VERSION=${GITHUB_REF:10}
47+
48+
if echo $VERSION | grep -q "$VER_REGEX"; then
49+
echo "version=${VERSION:1}" >> "$GITHUB_OUTPUT"
50+
else
51+
echo "Tag $VERSION does not follow v<version> naming scheme"
52+
exit 1
53+
fi
54+
- uses: actions/checkout@v4
55+
- name: Generate release body
56+
run: |
57+
sed "s/:VERSION/$VERSION/g" < .github/release-template.md > release.md
58+
cat release.md
59+
env:
60+
VERSION: ${{ steps.getrelease.outputs.version }}
61+
- name: Upload release body
62+
uses: actions/upload-artifact@v4
63+
with:
64+
name: release-body
65+
path: release.md
66+
build-wheels:
67+
runs-on: ${{ matrix.os }}
68+
needs: [extract-params]
69+
strategy:
70+
fail-fast: false
71+
matrix:
72+
os:
73+
- ubuntu-latest
74+
- ubuntu-24.04-arm
75+
- windows-latest
76+
- macos-latest
77+
steps:
78+
- uses: actions/checkout@v4
79+
- name: Setup Python
80+
uses: actions/setup-python@v5
81+
- name: Build wheels
82+
uses: pypa/[email protected]
83+
- uses: actions/upload-artifact@v4
84+
with:
85+
name: wheels-${{ matrix.os }}-${{ strategy.job-index }}
86+
path: ./wheelhouse/*.whl
87+
build-sdist:
88+
runs-on: ubuntu-latest
89+
needs: [extract-params]
90+
steps:
91+
- uses: actions/checkout@v4
92+
- name: Setup Python
93+
uses: actions/setup-python@v5
94+
- name: Install uv
95+
uses: astral-sh/setup-uv@v4
96+
with:
97+
enable-cache: true
98+
- name: Build source distribution
99+
run: uv build --sdist
100+
- uses: actions/upload-artifact@v4
101+
with:
102+
name: sdist
103+
path: ./dist/*.tar.gz
104+
publish:
105+
name: Publish release artifacts
106+
needs: [extract-params, build-sdist, build-wheels]
11107
runs-on: ubuntu-latest
12-
environment: release
108+
environment: ${{ needs.extract-params.outputs.publish-env }}
13109
permissions:
110+
# we use PyPI's trusted publisher model -> expose identity token
14111
id-token: write
112+
# Needed to create GitHub releases
113+
contents: write
15114
steps:
16-
- uses: actions/checkout@v4
17-
- uses: actions/setup-python@v5
18-
- run: pip install build
19-
- run: python -m build
20-
- name: Publish package distributions to PyPI
115+
- name: Download wheels
116+
uses: actions/download-artifact@v4
117+
with:
118+
pattern: wheels-*
119+
path: dist/
120+
merge-multiple: 'true'
121+
- name: Download source distribution
122+
uses: actions/download-artifact@v4
123+
with:
124+
name: sdist
125+
path: dist/
126+
- name: Download release body
127+
uses: actions/download-artifact@v4
128+
with:
129+
name: release-body
130+
path: release-body
131+
- name: Upload to PyPI
21132
uses: pypa/gh-action-pypi-publish@release/v1
133+
with:
134+
repository-url: ${{ vars.REPOSITORY_URL }}
135+
- name: Create GitHub release
136+
if: needs.extract-params.outputs.publish-env == 'pypi' && startsWith(github.ref, 'refs/tags/')
137+
uses: softprops/action-gh-release@v2
138+
with:
139+
files: |
140+
dist/*.whl
141+
dist/*.tar.gz
142+
body_path: release-body/release.md
143+
fail_on_unmatched_files: true
144+
name: python-pkcs11 ${{ needs.extract-params.outputs.version }}

.github/workflows/tests.yml

Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
name: Tests
22
on:
3-
push: {}
3+
push:
4+
branches: ["*"]
5+
pull_request: {}
46
workflow_dispatch: {}
57
env:
68
UV_PYTHON_PREFERENCE: only-system
7-
PKCS11_TOKEN_LABEL: TEST
8-
PKCS11_TOKEN_PIN: 1234
9-
PKCS11_TOKEN_SO_PIN: 5678
9+
UV_NO_SYNC: "1"
1010
jobs:
1111
run:
1212
runs-on: ${{ matrix.os }}
@@ -27,46 +27,21 @@ jobs:
2727

2828
steps:
2929
- name: Acquire sources
30-
uses: actions/checkout@v4.1.1
30+
uses: actions/checkout@v4
3131

3232
- name: Setup Python
33-
uses: actions/setup-python@v5.0.0
33+
uses: actions/setup-python@v5
3434
with:
3535
python-version: ${{ matrix.python-version }}
36-
- name: Install Softhsm
37-
shell: bash
38-
run: |
39-
if [[ $OS_NAME == 'ubuntu-latest' ]]; then
40-
sudo apt-get install softhsm2
41-
mkdir softhsm_tokens
42-
echo "directories.tokendir = $(pwd)/softhsm_tokens" > /tmp/softhsm2.conf
43-
echo "SOFTHSM2_CONF=/tmp/softhsm2.conf" >> "$GITHUB_ENV"
44-
echo "PKCS11_MODULE=/usr/lib/softhsm/libsofthsm2.so" >> "$GITHUB_ENV"
45-
elif [[ $OS_NAME == 'macos-latest' ]]; then
46-
brew install softhsm
47-
echo "PKCS11_MODULE=/opt/homebrew/lib/softhsm/libsofthsm2.so" >> "$GITHUB_ENV"
48-
elif [[ $OS_NAME == 'windows-latest' ]]; then
49-
choco install softhsm.install
50-
echo "SOFTHSM2_CONF=D:/SoftHSM2/etc/softhsm2.conf" >> "$GITHUB_ENV"
51-
echo "PKCS11_MODULE=D:/SoftHSM2/lib/softhsm2-x64.dll" >> "$GITHUB_ENV"
52-
echo "D:/SoftHSM2/bin" >> "$GITHUB_PATH"
53-
echo "D:/SoftHSM2/lib" >> "$GITHUB_PATH"
54-
else
55-
echo "$OS_NAME is not a supported target system"
56-
exit 1
57-
fi
58-
env:
59-
OS_NAME: ${{ matrix.os }}
60-
- name: Initialize SoftHSM token
61-
shell: bash
62-
run: |
63-
softhsm2-util --init-token --free --label $PKCS11_TOKEN_LABEL --pin $PKCS11_TOKEN_PIN --so-pin $PKCS11_TOKEN_SO_PIN
36+
- uses: ./.github/actions/install-softhsm
37+
with:
38+
os: ${{ matrix.os }}
6439
- name: Install uv
6540
uses: astral-sh/setup-uv@v4
6641
with:
6742
enable-cache: true
6843
python-version: ${{ matrix.python-version }}
69-
- name: Install dev dependencies
70-
run: uv sync --all-extras
44+
- name: Install testing dependencies
45+
run: uv sync --no-dev --exact --group testing
7146
- name: Run tests
7247
run: uv run pytest -v

.readthedocs.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
version: 2
2+
3+
build:
4+
os: ubuntu-24.04
5+
tools:
6+
python: "3.12"
7+
# readthedocs does not support [dependency-groups] directly
8+
jobs:
9+
create_environment:
10+
- asdf plugin add uv
11+
- asdf install uv latest
12+
- asdf global uv latest
13+
build:
14+
html:
15+
- make -C docs html BUILDDIR=$READTHEDOCS_OUTPUT
16+
formats: all

docs/Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22
#
33

44
# You can set these variables from the command line.
5-
SPHINXOPTS =
6-
SPHINXBUILD = python -msphinx
5+
SPHINXOPTS ?=
6+
SPHINXBUILD ?= sphinx-build
77
SPHINXPROJ = PythonPKCS11
88
SOURCEDIR = .
99
BUILDDIR = _build
1010

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

1515
.PHONY: help Makefile
1616

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

0 commit comments

Comments
 (0)