Repository navigation
113 lines (104 loc) · 5.16 KB
/
Copy pathpython-package.yml
File metadata and controls
113 lines (104 loc) · 5.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
name: Python package
on: [push, pull_request]
jobs:
# Catch version drift at commit time, not at release time. The publish workflow already
# refuses a tag that disagrees with the manifest, but that only fires on a tag push, so
# drift can sit in master until release day. Same script, no expected version: assert only
# that the repo agrees with itself.
version:
name: version consistency
runs-on: ubuntu-latest
steps:
# persist-credentials: false (2026-08) — nothing here pushes; a kept token is readable from .git/config.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Declared versions agree
run: bash .github/scripts/check-version.sh
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install --require-hashes -r requirements-dev.lock
# Dependency audit gate: fail on known advisories in the runtime floors, the
# committed lock (requirements.lock is the reproducible CI resolution), the
# dev toolchain — the dev set is where a build-time supply-chain attack lands,
# and it was the one requirement file nothing scanned until 2026-08 — and the
# hashed dev lock this job installs from.
- name: pip-audit
run: |
pip-audit -r requirements.txt
pip-audit -r requirements.lock
pip-audit -r requirements-dev.txt
pip-audit -r requirements-dev.lock
- name: Set up Node.js (for the ML-KEM noble bridge)
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: '20'
- name: Install ML-KEM bridge deps (@noble/post-quantum)
working-directory: bin
run: npm ci
# libkcore for this runner, from the sha256-pinned KnishIO-Crypto-Core Release, so the suite
# runs once through kcore and once through the pure-Python/Node-bridge fallback.
- name: Fetch libkcore (linux-x64-gnu)
run: python scripts/fetch_kcore.py --target linux-x64-gnu
- name: Lint with ruff
run: |
# Enforced gate (config in pyproject.toml [tool.ruff.lint]): syntax errors (E9)
# + pyflakes real bugs (F) + None/bool comparison (E711/E712), over the shipped
# package + tests. F821 (undefined name) stays relaxed — the SDK uses quoted
# forward-reference annotations ("Molecule"/"KnishIOClient"/…) for circular-import
# avoidance, which pyflakes false-flags (the old flake8 gate omitted F82 for the same reason).
ruff check
- name: Test with pytest (libkcore required, then switched off)
run: |
KNISHIO_KCORE=require pytest
KNISHIO_KCORE=off pytest
wheels:
name: wheels
uses: ./.github/workflows/wheels.yml
changelog:
name: changelog entry for version bump
runs-on: ubuntu-latest
steps:
# fetch-depth: 0 — the gate diffs against the base commit, which a shallow
# checkout would not have.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
# If knishioclient/__init__.py's __version__ changed relative to the base commit,
# CHANGELOG.md must carry a matching `## [<version>]` heading. No change → no-op.
# Versions are PEP 440 (e.g. 0.9.2.post1), so the match is on the literal string.
# Convention: docs/SDK-RELEASE-CONVENTIONS.md in the KnishIOClientSDK monorepo.
- name: CHANGELOG entry for the manifest version bump
# BASE arrives via env, never interpolated into the shell text (workflow-injection hygiene).
env:
BASE: ${{ github.event.pull_request.base.sha || github.event.before }}
run: |
set -eu
BASE="${BASE:-}"
if [ -z "$BASE" ] || [ "$BASE" = '0000000000000000000000000000000000000000' ] \
|| ! git cat-file -e "$BASE^{commit}" 2>/dev/null; then
echo "No comparable base commit — changelog gate skipped."; exit 0
fi
ver() { sed -n "s/^__version__[[:space:]]*=[[:space:]]*['\"]\([^'\"]*\)['\"].*/\1/p" "$1" | head -1; }
git show "$BASE:knishioclient/__init__.py" > /tmp/base-manifest 2>/dev/null || : > /tmp/base-manifest
NEW=$(ver knishioclient/__init__.py); OLD=$(ver /tmp/base-manifest)
if [ "$NEW" = "$OLD" ]; then echo "version unchanged ($NEW) — nothing to check."; exit 0; fi
echo "version bumped: ${OLD:-<none>} -> $NEW"
# index()==1 is a fixed-string match anchored at column 1: no regex escaping of the
# version, and a deeper `### [x]` heading does NOT satisfy `## [x]` (grep -F would match it).
if ! awk -v h="## [$NEW]" 'index($0, h) == 1 { f = 1 } END { exit !f }' CHANGELOG.md; then
echo "::error file=CHANGELOG.md::Version bumped to $NEW but CHANGELOG.md has no '## [$NEW]' entry."
exit 1
fi
echo "OK: CHANGELOG.md documents $NEW"