hypernix 0.32.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. hypernix-0.32.0/.github/workflows/build.yml +197 -0
  2. hypernix-0.32.0/.github/workflows/ci.yml +87 -0
  3. hypernix-0.32.0/.github/workflows/public-release.yml +313 -0
  4. hypernix-0.32.0/.github/workflows/release.yml +214 -0
  5. hypernix-0.32.0/LICENSE +17 -0
  6. hypernix-0.32.0/MANIFEST.in +23 -0
  7. hypernix-0.32.0/PKG-INFO +353 -0
  8. hypernix-0.32.0/README.md +310 -0
  9. hypernix-0.32.0/examples/custom_arch.py +52 -0
  10. hypernix-0.32.0/examples/quickstart.py +28 -0
  11. hypernix-0.32.0/examples/run_hypernix.py +146 -0
  12. hypernix-0.32.0/examples/upload_to_hub.py +26 -0
  13. hypernix-0.32.0/pyproject.toml +88 -0
  14. hypernix-0.32.0/pytest.ini +5 -0
  15. hypernix-0.32.0/ruff.toml +6 -0
  16. hypernix-0.32.0/scripts/install_deps.sh +97 -0
  17. hypernix-0.32.0/scripts/quantize_i7_7660u.sh +107 -0
  18. hypernix-0.32.0/setup.cfg +63 -0
  19. hypernix-0.32.0/setup.py +11 -0
  20. hypernix-0.32.0/src/hypernix/__init__.py +68 -0
  21. hypernix-0.32.0/src/hypernix/__main__.py +4 -0
  22. hypernix-0.32.0/src/hypernix/arch.py +174 -0
  23. hypernix-0.32.0/src/hypernix/cli.py +762 -0
  24. hypernix-0.32.0/src/hypernix/convert.py +277 -0
  25. hypernix-0.32.0/src/hypernix/doctor.py +113 -0
  26. hypernix-0.32.0/src/hypernix/download.py +254 -0
  27. hypernix-0.32.0/src/hypernix/fetcher.py +259 -0
  28. hypernix-0.32.0/src/hypernix/generate.py +136 -0
  29. hypernix-0.32.0/src/hypernix/nano_nano.py +213 -0
  30. hypernix-0.32.0/src/hypernix/old_oven.py +641 -0
  31. hypernix-0.32.0/src/hypernix/py.typed +0 -0
  32. hypernix-0.32.0/src/hypernix/quantize.py +285 -0
  33. hypernix-0.32.0/src/hypernix/train.py +555 -0
  34. hypernix-0.32.0/src/hypernix/upload.py +61 -0
  35. hypernix-0.32.0/src/hypernix.egg-info/SOURCES.txt +38 -0
  36. hypernix-0.32.0/tests/test_arch_mapping.py +42 -0
  37. hypernix-0.32.0/tests/test_fetcher.py +102 -0
  38. hypernix-0.32.0/tests/test_old_oven.py +230 -0
  39. hypernix-0.32.0/tests/test_snapshot_roundtrip.py +128 -0
  40. hypernix-0.32.0/tests/test_v031_chat_and_archs.py +285 -0
@@ -0,0 +1,197 @@
1
+ name: build
2
+
3
+ # Reusable build pipeline. Can be invoked:
4
+ # - directly (workflow_dispatch) -> uploads artifacts for download
5
+ # - from release.yml (workflow_call) -> release consumes the artifact
6
+ # - on push to main touching packaging/source -> sanity check
7
+ #
8
+ # Produces, for every invocation:
9
+ # dist/hypernix-<ver>-py3-none-any.whl
10
+ # dist/hypernix-<ver>.tar.gz
11
+ # dist/hypernix-<ver>-scripts-examples.tar.gz
12
+ # dist/SHA256SUMS
13
+
14
+ on:
15
+ workflow_call:
16
+ outputs:
17
+ version:
18
+ description: "Version that was built (PEP 440)."
19
+ value: ${{ jobs.build.outputs.version }}
20
+ artifact_name:
21
+ description: "Name of the uploaded artifact."
22
+ value: ${{ jobs.build.outputs.artifact_name }}
23
+ workflow_dispatch:
24
+ push:
25
+ branches: [main, master]
26
+ paths:
27
+ - "src/**"
28
+ - "pyproject.toml"
29
+ - "setup.py"
30
+ - "setup.cfg"
31
+ - "MANIFEST.in"
32
+ - "README.md"
33
+ - ".github/workflows/build.yml"
34
+
35
+ permissions:
36
+ contents: read
37
+
38
+ jobs:
39
+ build:
40
+ name: build sdist + wheel + extras
41
+ runs-on: ubuntu-latest
42
+ outputs:
43
+ version: ${{ steps.meta.outputs.version }}
44
+ artifact_name: ${{ steps.meta.outputs.artifact_name }}
45
+
46
+ steps:
47
+ - name: Checkout
48
+ uses: actions/checkout@v4
49
+ with:
50
+ fetch-depth: 0
51
+
52
+ - name: Setup Python 3.12
53
+ uses: actions/setup-python@v5
54
+ with:
55
+ python-version: "3.12"
56
+ cache: pip
57
+
58
+ - name: Install build tooling
59
+ run: |
60
+ python -m pip install --upgrade pip
61
+ pip install "build>=1.2" "twine>=5" "setuptools>=77" wheel
62
+
63
+ - name: Read package metadata
64
+ id: meta
65
+ run: |
66
+ version=$(python -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])')
67
+ name=$(python -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["name"])')
68
+ echo "version=$version" >> "$GITHUB_OUTPUT"
69
+ echo "name=$name" >> "$GITHUB_OUTPUT"
70
+ echo "artifact_name=${name}-dist-${version}-${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
71
+ echo "::notice::building $name $version"
72
+
73
+ - name: Build sdist + wheel
74
+ run: python -m build
75
+
76
+ - name: twine check (strict)
77
+ run: twine check --strict dist/*
78
+
79
+ - name: Install wheel in a clean venv and smoke-test the CLI
80
+ run: |
81
+ python -m venv /tmp/install-check
82
+ . /tmp/install-check/bin/activate
83
+ pip install --upgrade pip
84
+ # torch from the CPU index keeps CI wall time reasonable.
85
+ pip install --index-url https://download.pytorch.org/whl/cpu torch==2.7.1
86
+ pip install dist/*.whl
87
+ python -c "import hypernix; print('hypernix', hypernix.__version__)"
88
+ hypernix --help
89
+ hypernix doctor || true # llama-quantize is absent on the runner; non-fatal
90
+
91
+ - name: Install sdist in a clean venv and smoke-test
92
+ run: |
93
+ python -m venv /tmp/sdist-check
94
+ . /tmp/sdist-check/bin/activate
95
+ pip install --upgrade pip
96
+ pip install --index-url https://download.pytorch.org/whl/cpu torch==2.7.1
97
+ pip install dist/*.tar.gz
98
+ hypernix --help
99
+
100
+ - name: Bundle scripts + examples for non-pip users
101
+ run: |
102
+ tar -czf "dist/${{ steps.meta.outputs.name }}-${{ steps.meta.outputs.version }}-scripts-examples.tar.gz" \
103
+ README.md LICENSE scripts examples
104
+
105
+ - name: Generate SHA256SUMS
106
+ working-directory: dist
107
+ run: |
108
+ # Exclude any pre-existing checksum file from the hashing step.
109
+ sha256sum *.whl *.tar.gz | tee SHA256SUMS
110
+
111
+ - name: Write INSTALL.txt into the artifact
112
+ working-directory: dist
113
+ run: |
114
+ cat > INSTALL.txt <<EOF
115
+ hypernix ${{ steps.meta.outputs.version }} build artifact
116
+ ============================================================
117
+
118
+ GitHub wraps multi-file artifacts in a .zip when you download them
119
+ from the Actions page. You CANNOT \`pip install\` that outer zip —
120
+ extract it first, then install the wheel or sdist from inside.
121
+
122
+ ------------------------------------------------------------------
123
+ Linux / macOS
124
+ ------------------------------------------------------------------
125
+ unzip hypernix-dist-*.zip -d hypernix-dist
126
+ cd hypernix-dist
127
+ python3.12 -m pip install hypernix-${{ steps.meta.outputs.version }}-py3-none-any.whl
128
+
129
+ If you don't have system permissions:
130
+ python3.12 -m pip install --user hypernix-${{ steps.meta.outputs.version }}-py3-none-any.whl
131
+ Or on Debian/Ubuntu 24.04+ (PEP 668):
132
+ python3.12 -m pip install --break-system-packages hypernix-${{ steps.meta.outputs.version }}-py3-none-any.whl
133
+
134
+ ------------------------------------------------------------------
135
+ Windows (PowerShell)
136
+ ------------------------------------------------------------------
137
+ Expand-Archive hypernix-dist-*.zip hypernix-dist
138
+ py -3.12 -m pip install hypernix-dist\hypernix-${{ steps.meta.outputs.version }}-py3-none-any.whl
139
+
140
+ ------------------------------------------------------------------
141
+ With the k-quant binary (recommended)
142
+ ------------------------------------------------------------------
143
+ python3.12 -m pip install 'hypernix-${{ steps.meta.outputs.version }}-py3-none-any.whl[llama-cpp]'
144
+
145
+ ------------------------------------------------------------------
146
+ Contents
147
+ ------------------------------------------------------------------
148
+ hypernix-${{ steps.meta.outputs.version }}-py3-none-any.whl
149
+ The installable wheel. Use this 99% of the time.
150
+ hypernix-${{ steps.meta.outputs.version }}.tar.gz
151
+ Source distribution (sdist). pip install works on this too.
152
+ hypernix-${{ steps.meta.outputs.version }}-scripts-examples.tar.gz
153
+ Bonus: shell scripts + Python examples + README + LICENSE,
154
+ for users who don't want pip.
155
+ SHA256SUMS
156
+ Verify downloads with: sha256sum --check SHA256SUMS
157
+
158
+ ------------------------------------------------------------------
159
+ Verify after install
160
+ ------------------------------------------------------------------
161
+ hypernix --help
162
+ hypernix doctor
163
+ EOF
164
+ echo "wrote $(wc -l < INSTALL.txt) lines"
165
+
166
+ - name: List final dist/
167
+ run: ls -lah dist/
168
+
169
+ - name: Upload artifact
170
+ uses: actions/upload-artifact@v4
171
+ with:
172
+ name: ${{ steps.meta.outputs.artifact_name }}
173
+ path: dist/*
174
+ if-no-files-found: error
175
+ retention-days: 90
176
+ compression-level: 0 # dist/* is already compressed
177
+
178
+ # Also upload the wheel alone under a stable name so downstream jobs
179
+ # (or CLI users running `gh run download --name hypernix-wheel`) can
180
+ # grab something that pip accepts directly without unwrapping a zip.
181
+ - name: Upload wheel-only artifact
182
+ uses: actions/upload-artifact@v4
183
+ with:
184
+ name: hypernix-wheel-${{ steps.meta.outputs.version }}
185
+ path: dist/*.whl
186
+ if-no-files-found: error
187
+ retention-days: 90
188
+
189
+ - name: Upload sdist-only artifact
190
+ uses: actions/upload-artifact@v4
191
+ with:
192
+ name: hypernix-sdist-${{ steps.meta.outputs.version }}
193
+ # Use an explicit filename, not *.tar.gz, so the scripts+examples
194
+ # bundle isn't swept into the "sdist" artifact.
195
+ path: dist/hypernix-${{ steps.meta.outputs.version }}.tar.gz
196
+ if-no-files-found: error
197
+ retention-days: 90
@@ -0,0 +1,87 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ concurrency:
13
+ group: ci-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
16
+ jobs:
17
+ lint:
18
+ name: ruff lint
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ - uses: actions/setup-python@v5
23
+ with:
24
+ python-version: "3.12"
25
+ cache: pip
26
+ - run: pip install "ruff>=0.5"
27
+ - run: ruff check src tests
28
+
29
+ test:
30
+ name: test (py${{ matrix.python-version }} on ${{ matrix.os }})
31
+ runs-on: ${{ matrix.os }}
32
+ strategy:
33
+ fail-fast: false
34
+ matrix:
35
+ os: [ubuntu-latest, ubuntu-22.04]
36
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
37
+ steps:
38
+ - uses: actions/checkout@v4
39
+
40
+ - uses: actions/setup-python@v5
41
+ with:
42
+ python-version: ${{ matrix.python-version }}
43
+ cache: pip
44
+
45
+ - name: Install torch (CPU wheels)
46
+ run: |
47
+ python -m pip install --upgrade pip
48
+ pip install --index-url https://download.pytorch.org/whl/cpu torch==2.7.1
49
+
50
+ - name: Editable install + dev extras
51
+ run: pip install -e ".[dev]"
52
+
53
+ - name: pytest
54
+ run: pytest -q
55
+
56
+ - name: CLI smoke tests
57
+ run: |
58
+ hypernix --help
59
+ python -m hypernix --help
60
+ hypernix doctor || true
61
+
62
+ - name: setup.py compatibility
63
+ run: |
64
+ python setup.py --name
65
+ python setup.py --version
66
+
67
+ build-check:
68
+ name: build sdist + wheel (smoke)
69
+ runs-on: ubuntu-latest
70
+ steps:
71
+ - uses: actions/checkout@v4
72
+ - uses: actions/setup-python@v5
73
+ with:
74
+ python-version: "3.12"
75
+ cache: pip
76
+ - run: pip install --upgrade pip build twine
77
+ - run: python -m build
78
+ - run: twine check --strict dist/*
79
+ - name: Verify extras are present in sdist
80
+ run: |
81
+ tar tzf dist/*.tar.gz | tee /tmp/sdist-listing
82
+ for required in tests examples scripts .github/workflows MANIFEST.in setup.py setup.cfg; do
83
+ if ! grep -q "/$required" /tmp/sdist-listing; then
84
+ echo "::error::sdist missing $required"
85
+ exit 1
86
+ fi
87
+ done
@@ -0,0 +1,313 @@
1
+ name: public-release
2
+
3
+ # One-click public release — does EVERYTHING in this single workflow so we
4
+ # don't depend on the tag push firing a second workflow (GITHUB_TOKEN-pushed
5
+ # tags intentionally don't trigger downstream workflows on GitHub).
6
+ #
7
+ # 1. Manual dispatch with a version (e.g. 0.2.0 or 0.2.0-rc1).
8
+ # 2. Updates pyproject.toml + setup.cfg + src/hypernix/__init__.py so the
9
+ # three version strings stay in sync.
10
+ # 3. Runs lint + tests + `python -m build` + `twine check` so we never
11
+ # tag a broken state.
12
+ # 4. Commits the version bump to the trigger branch (skip-ci-tagged).
13
+ # 5. Creates an annotated tag `v<version>` and pushes it.
14
+ # 6. Downstream jobs (github-release, pypi-publish, testpypi-publish)
15
+ # consume the built artifact and create the GitHub Release + publish
16
+ # to PyPI (stable) or TestPyPI (prerelease) via Trusted Publishing.
17
+ #
18
+ # Net effect: kick this off once from the Actions tab and a public release
19
+ # lands on PyPI with `pip install hypernix` working immediately after.
20
+ #
21
+ # Prereqs (one-time, by the repo owner):
22
+ # - Register Trusted Publishing on PyPI at
23
+ # https://pypi.org/manage/account/publishing/:
24
+ # project = hypernix
25
+ # owner = <your_gh_org>
26
+ # repo = hypernix-pip
27
+ # workflow = public-release.yml
28
+ # environment = pypi
29
+ # - Same for TestPyPI (environment = testpypi) if you want prerelease
30
+ # publishing.
31
+
32
+ on:
33
+ workflow_dispatch:
34
+ inputs:
35
+ version:
36
+ description: "New version, without the leading v (e.g. 0.2.0 or 0.2.0-rc1)."
37
+ required: true
38
+ type: string
39
+ dry_run:
40
+ description: "Validate + build but skip the commit, tag push, and publish."
41
+ type: boolean
42
+ default: false
43
+ skip_pypi:
44
+ description: "Tag + GitHub Release but skip PyPI / TestPyPI publishing."
45
+ type: boolean
46
+ default: false
47
+
48
+ concurrency:
49
+ group: public-release-${{ github.ref }}
50
+ cancel-in-progress: false
51
+
52
+ jobs:
53
+ # ---------------------------------------------------------------------------
54
+ # Validate, build, test, tag, push. Uploads dist/ as an artifact the
55
+ # downstream publish jobs consume.
56
+ # ---------------------------------------------------------------------------
57
+ cut:
58
+ name: cut public release v${{ inputs.version }}
59
+ runs-on: ubuntu-latest
60
+ permissions:
61
+ contents: write # commit version bump + push tag
62
+ outputs:
63
+ prerelease: ${{ steps.classify.outputs.prerelease }}
64
+ tag: ${{ steps.classify.outputs.tag }}
65
+ steps:
66
+ - name: Validate version format
67
+ run: |
68
+ v='${{ inputs.version }}'
69
+ if ! [[ "$v" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-]?(rc|pre|alpha|beta|a|b)[0-9]*)?$ ]]; then
70
+ echo "::error::version '$v' is not PEP 440-ish (e.g. 0.2.0, 0.2.0-rc1, 0.2.0a2)"
71
+ exit 1
72
+ fi
73
+
74
+ - name: Classify release (stable vs prerelease)
75
+ id: classify
76
+ run: |
77
+ v='${{ inputs.version }}'
78
+ tag="v$v"
79
+ if [[ "$v" =~ (rc|pre|alpha|beta|a|b)[0-9]*$ ]]; then
80
+ echo "prerelease=true" >> "$GITHUB_OUTPUT"
81
+ echo "::notice::$tag is a prerelease (-> TestPyPI)"
82
+ else
83
+ echo "prerelease=false" >> "$GITHUB_OUTPUT"
84
+ echo "::notice::$tag is a stable release (-> PyPI)"
85
+ fi
86
+ echo "tag=$tag" >> "$GITHUB_OUTPUT"
87
+
88
+ - name: Checkout
89
+ uses: actions/checkout@v4
90
+ with:
91
+ fetch-depth: 0
92
+ token: ${{ secrets.GITHUB_TOKEN }}
93
+
94
+ - name: Setup Python 3.12
95
+ uses: actions/setup-python@v5
96
+ with:
97
+ python-version: "3.12"
98
+ cache: pip
99
+
100
+ - name: Install tooling
101
+ run: |
102
+ python -m pip install --upgrade pip
103
+ pip install --upgrade "packaging>=24.2"
104
+ pip install "build>=1.2" "twine>=6" "ruff>=0.5" "pytest>=8" "setuptools>=77" wheel
105
+
106
+ - name: Install torch (CPU wheels) + package
107
+ # pytest needs torch (hypernix imports it at module load). Install the
108
+ # CPU wheel explicitly rather than relying on the package install
109
+ # below to pull it, so we never accidentally fetch a GPU build.
110
+ run: |
111
+ pip install --index-url https://download.pytorch.org/whl/cpu torch
112
+ pip install -e ".[dev]"
113
+
114
+ - name: Bump versions in source
115
+ run: |
116
+ v='${{ inputs.version }}'
117
+ python - <<PY
118
+ import re
119
+ from pathlib import Path
120
+
121
+ v = "${{ inputs.version }}"
122
+
123
+ p = Path("pyproject.toml")
124
+ p.write_text(re.sub(r'^version = "[^"]+"', f'version = "{v}"', p.read_text(), count=1, flags=re.M))
125
+
126
+ s = Path("setup.cfg")
127
+ s.write_text(re.sub(r'^version = .+$', f'version = {v}', s.read_text(), count=1, flags=re.M))
128
+
129
+ init = Path("src/hypernix/__init__.py")
130
+ init.write_text(re.sub(r'__version__ = "[^"]+"', f'__version__ = "{v}"', init.read_text(), count=1))
131
+ PY
132
+ echo "--- pyproject.toml version line"
133
+ grep '^version' pyproject.toml
134
+ echo "--- setup.cfg version line"
135
+ grep '^version' setup.cfg
136
+ echo "--- __init__.py version line"
137
+ grep __version__ src/hypernix/__init__.py
138
+
139
+ - name: Lint
140
+ run: ruff check src/hypernix
141
+
142
+ - name: Tests
143
+ run: PYTHONPATH=src pytest -q
144
+
145
+ - name: Build sdist + wheel
146
+ run: python -m build
147
+
148
+ - name: Twine check
149
+ run: twine check --strict dist/*
150
+
151
+ - name: Generate CHANGELOG fragment
152
+ id: changelog
153
+ run: |
154
+ last=$(git describe --tags --abbrev=0 2>/dev/null || true)
155
+ {
156
+ echo "## Changelog"
157
+ echo ""
158
+ if [ -n "$last" ]; then
159
+ echo "Commits since \`$last\`:"
160
+ echo ""
161
+ git log "$last..HEAD" --pretty='- %s (%h)' --no-merges
162
+ else
163
+ echo "Initial tagged release."
164
+ fi
165
+ } > CHANGELOG_FRAGMENT.md
166
+ echo "--- fragment ---"
167
+ cat CHANGELOG_FRAGMENT.md
168
+
169
+ - name: Generate SHA256SUMS
170
+ working-directory: dist
171
+ run: sha256sum *.whl *.tar.gz | tee SHA256SUMS
172
+
173
+ - name: Upload build artifacts
174
+ uses: actions/upload-artifact@v4
175
+ with:
176
+ name: public-release-${{ inputs.dry_run && 'dryrun-' || '' }}${{ inputs.version }}
177
+ path: |
178
+ dist/
179
+ CHANGELOG_FRAGMENT.md
180
+ retention-days: 14
181
+
182
+ - name: Commit version bump
183
+ if: ${{ !inputs.dry_run }}
184
+ run: |
185
+ git config user.name "github-actions[bot]"
186
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
187
+ git add pyproject.toml setup.cfg src/hypernix/__init__.py
188
+ if git diff --cached --quiet; then
189
+ echo "::notice::no version change to commit (already at v${{ inputs.version }})"
190
+ else
191
+ git commit -m "hypernix v${{ inputs.version }} [skip ci]"
192
+ git push origin HEAD:${{ github.ref_name }}
193
+ fi
194
+
195
+ - name: Tag and push
196
+ if: ${{ !inputs.dry_run }}
197
+ run: |
198
+ tag='${{ steps.classify.outputs.tag }}'
199
+ if git rev-parse "$tag" >/dev/null 2>&1; then
200
+ echo "::notice::tag $tag already exists; skipping tag push"
201
+ else
202
+ git tag -a "$tag" -F CHANGELOG_FRAGMENT.md
203
+ git push origin "$tag"
204
+ echo "::notice::pushed $tag"
205
+ fi
206
+
207
+ # ---------------------------------------------------------------------------
208
+ # Create the GitHub Release and attach the built artifacts + SHA256SUMS.
209
+ # ---------------------------------------------------------------------------
210
+ github-release:
211
+ name: GitHub Release
212
+ needs: cut
213
+ if: ${{ !inputs.dry_run }}
214
+ runs-on: ubuntu-latest
215
+ permissions:
216
+ contents: write
217
+ steps:
218
+ - name: Download build artifact
219
+ uses: actions/download-artifact@v4
220
+ with:
221
+ name: public-release-${{ inputs.version }}
222
+ path: .
223
+
224
+ - name: Show artifacts
225
+ run: ls -lah dist/
226
+
227
+ - name: Create Release
228
+ uses: softprops/action-gh-release@v2
229
+ with:
230
+ tag_name: ${{ needs.cut.outputs.tag }}
231
+ name: hypernix ${{ needs.cut.outputs.tag }}
232
+ prerelease: ${{ needs.cut.outputs.prerelease == 'true' }}
233
+ body_path: CHANGELOG_FRAGMENT.md
234
+ files: |
235
+ dist/*.whl
236
+ dist/*.tar.gz
237
+ dist/SHA256SUMS
238
+
239
+ # ---------------------------------------------------------------------------
240
+ # Publish stable tags to real PyPI via Trusted Publishing (OIDC).
241
+ # Requires configuring the PyPI project with:
242
+ # publisher = GitHub
243
+ # repo = minerofthesoal/hypernix-pip
244
+ # workflow = public-release.yml
245
+ # environment = pypi
246
+ # ---------------------------------------------------------------------------
247
+ pypi-publish:
248
+ name: publish to PyPI
249
+ needs: cut
250
+ if: >-
251
+ !inputs.dry_run &&
252
+ !inputs.skip_pypi &&
253
+ needs.cut.outputs.prerelease == 'false'
254
+ runs-on: ubuntu-latest
255
+ permissions:
256
+ id-token: write
257
+ environment:
258
+ name: pypi
259
+ url: https://pypi.org/project/hypernix/
260
+ steps:
261
+ - name: Download build artifact
262
+ uses: actions/download-artifact@v4
263
+ with:
264
+ name: public-release-${{ inputs.version }}
265
+ path: .
266
+
267
+ - name: Strip non-PyPI files
268
+ run: |
269
+ cd dist
270
+ rm -f SHA256SUMS
271
+ ls -lah
272
+
273
+ - name: Publish
274
+ uses: pypa/gh-action-pypi-publish@release/v1
275
+ with:
276
+ packages-dir: dist
277
+ skip-existing: true
278
+
279
+ # ---------------------------------------------------------------------------
280
+ # Publish prereleases to TestPyPI. Same OIDC setup, different environment.
281
+ # ---------------------------------------------------------------------------
282
+ testpypi-publish:
283
+ name: publish to TestPyPI
284
+ needs: cut
285
+ if: >-
286
+ !inputs.dry_run &&
287
+ !inputs.skip_pypi &&
288
+ needs.cut.outputs.prerelease == 'true'
289
+ runs-on: ubuntu-latest
290
+ permissions:
291
+ id-token: write
292
+ environment:
293
+ name: testpypi
294
+ url: https://test.pypi.org/project/hypernix/
295
+ steps:
296
+ - name: Download build artifact
297
+ uses: actions/download-artifact@v4
298
+ with:
299
+ name: public-release-${{ inputs.version }}
300
+ path: .
301
+
302
+ - name: Strip non-PyPI files
303
+ run: |
304
+ cd dist
305
+ rm -f SHA256SUMS
306
+ ls -lah
307
+
308
+ - name: Publish
309
+ uses: pypa/gh-action-pypi-publish@release/v1
310
+ with:
311
+ packages-dir: dist
312
+ repository-url: https://test.pypi.org/legacy/
313
+ skip-existing: true