Skip to content

Commit a11bfdb

Browse files
author
fer
committed
feat: Add PyPI and Zenodo integration files
- Add .zenodo.json for Zenodo metadata - Add CITATION.cff for academic citations - Add PyPI/Zenodo GitHub workflow - Add release automation script - Update MANIFEST.in to include new files
1 parent 422e6d4 commit a11bfdb

File tree

4 files changed

+233
-0
lines changed

4 files changed

+233
-0
lines changed

.github/workflows/pypi-zenodo.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: PyPI and Zenodo Integration
2+
3+
on:
4+
release:
5+
types: [published]
6+
workflow_dispatch:
7+
inputs:
8+
force_publish:
9+
description: 'Force publish to PyPI'
10+
required: false
11+
default: false
12+
type: boolean
13+
14+
jobs:
15+
pypi-publish:
16+
runs-on: ubuntu-latest
17+
permissions:
18+
contents: read
19+
id-token: write # For trusted publishing to PyPI
20+
21+
steps:
22+
- uses: actions/checkout@v4
23+
with:
24+
fetch-depth: 0
25+
26+
- name: Set up Python
27+
uses: actions/setup-python@v4
28+
with:
29+
python-version: '3.11'
30+
31+
- name: Install build dependencies
32+
run: |
33+
python -m pip install --upgrade pip
34+
pip install build setuptools-scm[toml] twine
35+
36+
- name: Build distribution
37+
run: python -m build
38+
39+
- name: Check distribution
40+
run: python -m twine check dist/*
41+
42+
- name: Publish to PyPI
43+
if: github.event_name == 'release' || inputs.force_publish
44+
uses: pypa/gh-action-pypi-publish@release/v1
45+
with:
46+
verbose: true
47+
48+
- name: Upload to Zenodo
49+
if: github.event_name == 'release'
50+
run: |
51+
echo "Zenodo integration will be triggered automatically via GitHub-Zenodo webhook"
52+
echo "Make sure Zenodo webhook is configured at https://zenodo.org/account/settings/github/"

.zenodo.json

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"title": "TNFR-Python-Engine: Resonant Fractal Nature Theory Implementation",
3+
"description": "Canonical computational implementation of TNFR - a paradigm shift from modeling 'things' to modeling coherent patterns that persist through resonance. This Python package provides the complete TNFR physics engine including the 13 structural operators, unified grammar validation (U1-U6), and the four canonical structural fields (Φ_s, |∇φ|, K_φ, ξ_C). Features include: nodal equation dynamics (∂EPI/∂t = νf·ΔNFR), structural potential confinement, phase synchronization, and multi-scale coherence analysis.",
4+
"creators": [
5+
{
6+
"name": "FMG",
7+
"affiliation": "TNFR Research"
8+
}
9+
],
10+
"keywords": [
11+
"TNFR",
12+
"complex systems",
13+
"fractals",
14+
"resonance",
15+
"networks",
16+
"structural dynamics",
17+
"structural analysis",
18+
"nodal equation",
19+
"coherence",
20+
"phase synchronization"
21+
],
22+
"license": "MIT",
23+
"upload_type": "software",
24+
"access_right": "open",
25+
"language": "eng",
26+
"related_identifiers": [
27+
{
28+
"identifier": "https://github.com/fermga/TNFR-Python-Engine",
29+
"relation": "isSupplementTo",
30+
"resource_type": "software"
31+
},
32+
{
33+
"identifier": "https://pypi.org/project/tnfr/",
34+
"relation": "isIdenticalTo",
35+
"resource_type": "software"
36+
}
37+
],
38+
"subjects": [
39+
{
40+
"term": "Complex Systems",
41+
"scheme": "keyword"
42+
},
43+
{
44+
"term": "Network Theory",
45+
"scheme": "keyword"
46+
},
47+
{
48+
"term": "Fractal Dynamics",
49+
"scheme": "keyword"
50+
},
51+
{
52+
"term": "Structural Analysis",
53+
"scheme": "keyword"
54+
}
55+
]
56+
}

CITATION.cff

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
cff-version: 1.2.0
2+
title: "TNFR-Python-Engine: Resonant Fractal Nature Theory Implementation"
3+
message: "If you use this software, please cite it as below."
4+
type: software
5+
authors:
6+
- given-names: "FMG"
7+
family-names: ""
8+
affiliation: "TNFR Research"
9+
repository-code: "https://github.com/fermga/TNFR-Python-Engine"
10+
url: "https://pypi.org/project/tnfr/"
11+
abstract: >-
12+
Canonical computational implementation of TNFR - a paradigm shift from
13+
modeling 'things' to modeling coherent patterns that persist through resonance.
14+
This Python package provides the complete TNFR physics engine including the
15+
13 structural operators, unified grammar validation (U1-U6), and the four
16+
canonical structural fields (Φ_s, |∇φ|, K_φ, ξ_C).
17+
keywords:
18+
- "TNFR"
19+
- "complex systems"
20+
- "fractals"
21+
- "resonance"
22+
- "networks"
23+
- "structural dynamics"
24+
- "nodal equation"
25+
- "coherence"
26+
- "phase synchronization"
27+
license: MIT
28+
version: "9.0.0"
29+
date-released: "2025-11-13"

scripts/release.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Release automation script for TNFR-Python-Engine.
4+
5+
This script helps automate the release process to PyPI and ensures
6+
all metadata is properly updated.
7+
"""
8+
9+
import argparse
10+
import subprocess
11+
import sys
12+
from pathlib import Path
13+
14+
15+
def run_command(cmd, cwd=None, check=True):
16+
"""Run a command and return the result."""
17+
print(f"Running: {' '.join(cmd)}")
18+
result = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True)
19+
if check and result.returncode != 0:
20+
print(f"Error running command: {result.stderr}")
21+
sys.exit(1)
22+
return result
23+
24+
25+
def update_version_in_citation(version):
26+
"""Update version in CITATION.cff."""
27+
citation_file = Path("CITATION.cff")
28+
if citation_file.exists():
29+
content = citation_file.read_text()
30+
lines = content.split('\n')
31+
for i, line in enumerate(lines):
32+
if line.startswith('version:'):
33+
lines[i] = f'version: "{version}"'
34+
break
35+
citation_file.write_text('\n'.join(lines))
36+
print(f"Updated CITATION.cff with version {version}")
37+
38+
39+
def main():
40+
parser = argparse.ArgumentParser(description="Release TNFR to PyPI")
41+
parser.add_argument("version", help="Version to release (e.g., 9.0.1)")
42+
parser.add_argument("--dry-run", action="store_true", help="Perform a dry run")
43+
parser.add_argument("--skip-tests", action="store_true", help="Skip running tests")
44+
45+
args = parser.parse_args()
46+
version = args.version
47+
48+
# Ensure we're in the correct directory
49+
if not Path("pyproject.toml").exists():
50+
print("Error: Must be run from the project root directory")
51+
sys.exit(1)
52+
53+
print(f"Preparing release {version}")
54+
55+
# Update version in citation file
56+
update_version_in_citation(version)
57+
58+
# Run tests unless skipped
59+
if not args.skip_tests:
60+
print("Running tests...")
61+
run_command([sys.executable, "-m", "pytest", "tests/", "-x"])
62+
63+
# Clean previous builds
64+
print("Cleaning previous builds...")
65+
run_command([sys.executable, "-c", "import shutil; shutil.rmtree('dist', ignore_errors=True)"])
66+
run_command([sys.executable, "-c", "import shutil; shutil.rmtree('build', ignore_errors=True)"])
67+
68+
# Build the package
69+
print("Building package...")
70+
run_command([sys.executable, "-m", "build"])
71+
72+
# Check the distribution
73+
print("Checking distribution...")
74+
run_command([sys.executable, "-m", "twine", "check", "dist/*"])
75+
76+
if args.dry_run:
77+
print("Dry run complete. To actually release, run without --dry-run")
78+
return
79+
80+
# Create and push git tag
81+
tag = f"v{version}"
82+
print(f"Creating git tag {tag}")
83+
run_command(["git", "tag", tag])
84+
run_command(["git", "push", "origin", tag])
85+
86+
# Upload to PyPI
87+
print("Uploading to PyPI...")
88+
run_command([sys.executable, "-m", "twine", "upload", "dist/*"])
89+
90+
print(f"Successfully released version {version}")
91+
print(f"PyPI: https://pypi.org/project/tnfr/{version}/")
92+
print("GitHub Actions will handle Zenodo integration automatically.")
93+
94+
95+
if __name__ == "__main__":
96+
main()

0 commit comments

Comments
 (0)