Skip to content

Commit 7233178

Browse files
committed
[INIT] Initial commit
0 parents  commit 7233178

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+17003
-0
lines changed

.auto-changelog

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"template": "keepachangelog",
3+
"unreleased": true,
4+
"commitLimit": false,
5+
"ignoreCommitPattern": ".*(CHANGELOG|README).*",
6+
"sortCommits": "date"
7+
}

.github/workflows/docs.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Documentation
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
tags:
8+
- "v*"
9+
workflow_dispatch:
10+
11+
permissions:
12+
contents: write
13+
14+
jobs:
15+
deploy:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v5
19+
with:
20+
fetch-depth: 0
21+
22+
- uses: actions/setup-python@v5
23+
with:
24+
python-version: 3.x
25+
26+
- name: Install dependencies
27+
run: pip install -r requirements.mkdocs.txt
28+
29+
- name: Configure Git
30+
run: |
31+
git config user.name github-actions
32+
git config user.email github-actions@github.com
33+
34+
- name: Fetch gh-pages branch
35+
run: |
36+
if git ls-remote --exit-code --heads origin gh-pages > /dev/null 2>&1; then
37+
git fetch origin gh-pages:gh-pages
38+
echo "Fetched existing gh-pages branch"
39+
else
40+
echo "gh-pages branch does not exist yet, mike will create it"
41+
fi
42+
43+
- name: Deploy docs (versioned)
44+
env:
45+
GH_TOKEN: ${{ secrets.GH_TOKEN }}
46+
run: |
47+
VERSION=$(git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//' || echo "0.1.0")
48+
mike deploy --push --update-aliases "$VERSION" latest
49+
git fetch origin gh-pages:gh-pages --force
50+
mike set-default --push latest
51+
echo "Mike versions:"
52+
mike list

.github/workflows/release.yml

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
# This workflow handles the complete release process:
2+
# 1. Generate changelog from conventional commits
3+
# 2. Create a GitHub release with changelog content
4+
# 3. Build and publish Python package to PyPI
5+
6+
name: Release
7+
8+
on:
9+
push:
10+
tags:
11+
- "v*.*.*"
12+
workflow_dispatch:
13+
workflow_call:
14+
inputs:
15+
node-version:
16+
description: "Node.js version to use for changelog generation"
17+
type: string
18+
default: "20"
19+
python-version:
20+
description: "Python version to use for build and documentation"
21+
type: string
22+
default: "3.11"
23+
skip-changelog:
24+
description: "Skip changelog generation"
25+
type: boolean
26+
default: false
27+
skip-pypi:
28+
description: "Skip PyPI publishing"
29+
type: boolean
30+
default: false
31+
secrets:
32+
PIPY_USERNAME:
33+
description: "PyPI username for package publishing"
34+
required: false
35+
PIPY_API_TOKEN:
36+
description: "PyPI API token for package publishing"
37+
required: false
38+
39+
permissions:
40+
contents: write
41+
pages: write
42+
id-token: write
43+
44+
jobs:
45+
# Step 1: Generate changelog FIRST so it can be included in the release
46+
generate-changelog:
47+
name: Generate Changelog
48+
if: ${{ inputs.skip-changelog != true }}
49+
runs-on: ubuntu-latest
50+
outputs:
51+
changelog-section: ${{ steps.extract-changelog.outputs.section }}
52+
steps:
53+
- name: Checkout
54+
uses: actions/checkout@v4
55+
with:
56+
ref: main
57+
fetch-depth: 0
58+
59+
- name: Check for package.json
60+
id: check-npm
61+
run: |
62+
if [ -f "package.json" ]; then
63+
echo "exists=true" >> $GITHUB_OUTPUT
64+
else
65+
echo "exists=false" >> $GITHUB_OUTPUT
66+
echo "No package.json found, skipping changelog generation"
67+
fi
68+
69+
- name: Setup Node.js
70+
if: steps.check-npm.outputs.exists == 'true'
71+
uses: actions/setup-node@v4
72+
with:
73+
node-version: ${{ inputs.node-version || '20' }}
74+
75+
- name: Install dependencies
76+
if: steps.check-npm.outputs.exists == 'true'
77+
run: npm install && npm install -g auto-changelog
78+
79+
- name: Generate changelog
80+
if: steps.check-npm.outputs.exists == 'true'
81+
run: npm run changelog
82+
83+
- name: Extract changelog section for this release
84+
id: extract-changelog
85+
run: |
86+
TAG_NAME="${GITHUB_REF_NAME:-$(git describe --tags --abbrev=0)}"
87+
VERSION="${TAG_NAME#v}"
88+
89+
if [ ! -f "CHANGELOG.md" ]; then
90+
echo "section=No changelog available for this release." >> $GITHUB_OUTPUT
91+
exit 0
92+
fi
93+
94+
echo "Looking for version: ${VERSION} (tag: ${TAG_NAME})"
95+
96+
# Try multiple patterns to find the version section
97+
SECTION=$(awk "/^## \[v?${VERSION}\]/{found=1; next} /^## /{if(found) exit} found{print}" CHANGELOG.md)
98+
SECTION=$(echo "$SECTION" | sed '/^[[:space:]]*$/d' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
99+
100+
if [ -z "$SECTION" ]; then
101+
SECTION=$(awk "/^## \[${TAG_NAME}\]/{found=1; next} /^## /{if(found) exit} found{print}" CHANGELOG.md)
102+
SECTION=$(echo "$SECTION" | sed '/^[[:space:]]*$/d' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
103+
fi
104+
105+
if [ -z "$SECTION" ]; then
106+
SECTION=$(awk "/^## v?${VERSION}/{found=1; next} /^## /{if(found) exit} found{print}" CHANGELOG.md)
107+
SECTION=$(echo "$SECTION" | sed '/^[[:space:]]*$/d' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
108+
fi
109+
110+
if [ -z "$SECTION" ]; then
111+
if grep -q "## \[v\?${VERSION}\]" CHANGELOG.md || grep -q "## v\?${VERSION}" CHANGELOG.md; then
112+
SECTION="This release contains minor updates. See commit history for details."
113+
else
114+
SECTION="No changelog entry found for version ${VERSION}."
115+
fi
116+
fi
117+
118+
echo "section<<EOF" >> $GITHUB_OUTPUT
119+
echo "$SECTION" >> $GITHUB_OUTPUT
120+
echo "EOF" >> $GITHUB_OUTPUT
121+
122+
- name: Remove package-lock.json
123+
if: steps.check-npm.outputs.exists == 'true'
124+
run: rm -f package-lock.json
125+
126+
- name: Commit and push changelog
127+
if: steps.check-npm.outputs.exists == 'true'
128+
run: |
129+
git config --global user.name 'github-actions[bot]'
130+
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
131+
git add CHANGELOG.md
132+
if [ -n "$(git status --porcelain)" ]; then
133+
git commit -m '[DOC] CHANGELOG' -m '[skip ci]'
134+
git push origin main
135+
else
136+
echo "No changes to commit"
137+
fi
138+
139+
# Step 2: Create release WITH changelog content
140+
create-release:
141+
name: Create GitHub Release
142+
needs: generate-changelog
143+
if: ${{ always() && !cancelled() }}
144+
runs-on: ubuntu-latest
145+
steps:
146+
- name: Checkout
147+
uses: actions/checkout@v4
148+
with:
149+
ref: main
150+
151+
- name: Create draft release
152+
uses: softprops/action-gh-release@v2
153+
with:
154+
draft: true
155+
name: ${{ github.ref_name }}
156+
body: |
157+
## What's Changed
158+
159+
${{ needs.generate-changelog.outputs.changelog-section || 'No detailed changelog available for this release.' }}
160+
161+
---
162+
📄 **[View Full Changelog](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md)**
163+
164+
# Step 3: Build and publish to PyPI
165+
publish-pypi:
166+
name: Publish to PyPI
167+
needs: create-release
168+
if: ${{ always() && !cancelled() && inputs.skip-pypi != true && startsWith(github.ref, 'refs/tags/v') }}
169+
runs-on: ubuntu-latest
170+
steps:
171+
- name: Checkout code
172+
uses: actions/checkout@v4
173+
with:
174+
ref: ${{ github.ref }}
175+
fetch-depth: 0
176+
submodules: true
177+
178+
- name: Set up Python
179+
uses: actions/setup-python@v5
180+
with:
181+
python-version: ${{ inputs.python-version || '3.11' }}
182+
183+
- name: Install build dependencies
184+
run: |
185+
python -m pip install --upgrade pip
186+
pip install setuptools wheel twine build
187+
188+
- name: Build package
189+
run: |
190+
python -m build
191+
192+
- name: Publish package to PyPI
193+
env:
194+
TWINE_USERNAME: ${{ secrets.PIPY_USERNAME }}
195+
TWINE_PASSWORD: ${{ secrets.PIPY_API_TOKEN }}
196+
run: |
197+
twine upload dist/*

.gitignore

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.egg-info/
6+
dist/
7+
build/
8+
*.egg
9+
.eggs/
10+
.venv/
11+
venv/
12+
env/
13+
.env
14+
*.so
15+
*.dylib
16+
17+
# Testing
18+
.pytest_cache/
19+
.ruff_cache/
20+
.mypy_cache/
21+
htmlcov/
22+
.coverage
23+
24+
# Node
25+
node_modules/
26+
package-lock.json
27+
28+
# MkDocs
29+
site/
30+
31+
# OS
32+
*.log
33+
.DS_Store
34+
Thumbs.db
35+
36+
# IDE
37+
.vscode/settings.json
38+
39+
# AI tools
40+
.claude/
41+
.cursor/
42+
.aider*
43+
.copilot/

.scripts/git/Get-CurrentGitTag.ps1

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Get the latest tag
2+
$latestTag = git describe --tags (git rev-list --tags --max-count=1)
3+
4+
# Output the latest tag
5+
Write-Output "Current version: $latestTag"

.scripts/git/Update-GitTag.ps1

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
param (
2+
[string]$incrementType
3+
)
4+
5+
# Get the latest tag (handle case where no tags exist)
6+
try {
7+
$tagList = git rev-list --tags --max-count=1 2>$null
8+
if ($tagList) {
9+
$latestTag = git describe --tags $tagList 2>$null
10+
}
11+
else {
12+
$latestTag = $null
13+
}
14+
}
15+
catch {
16+
$latestTag = $null
17+
}
18+
19+
# If no tags exist, start with v0.1.0
20+
if (-not $latestTag) {
21+
Write-Host "No existing tags found. Creating initial version v0.1.0..."
22+
$newVersion = "0.1.0"
23+
git tag -a "v$newVersion" -m "Version $newVersion"
24+
git push origin "v$newVersion"
25+
Write-Host "Tag v$newVersion pushed."
26+
Write-Output $newVersion
27+
exit 0
28+
}
29+
30+
# Remove the 'v' prefix if it exists
31+
if ($latestTag.StartsWith('v')) {
32+
$latestTag = $latestTag.Substring(1)
33+
}
34+
35+
# Split the version into an array
36+
$versionParts = $latestTag -split '\.'
37+
38+
# Ensure the versionParts array has three elements
39+
if ($versionParts.Length -ne 3) {
40+
Write-Host "Error: The latest tag '$latestTag' is not in the expected format 'vX.Y.Z'."
41+
exit 1
42+
}
43+
44+
switch ($incrementType) {
45+
"major" {
46+
$versionParts[0] = [int]$versionParts[0] + 1
47+
$versionParts[1] = 0
48+
$versionParts[2] = 0
49+
}
50+
"minor" {
51+
$versionParts[1] = [int]$versionParts[1] + 1
52+
$versionParts[2] = 0
53+
}
54+
"patch" {
55+
$versionParts[2] = [int]$versionParts[2] + 1
56+
}
57+
default {
58+
Write-Host "Usage: .\Update-GitTag.ps1 {major|minor|patch}"
59+
exit 1
60+
}
61+
}
62+
63+
# Join the version parts into a new version string
64+
$newVersion = "$($versionParts[0]).$($versionParts[1]).$($versionParts[2])"
65+
66+
# Create and push the new tag (CI will handle the rest)
67+
git tag -a "v$newVersion" -m "Version $newVersion"
68+
git push origin "v$newVersion"
69+
70+
Write-Host "Tag v$newVersion pushed."
71+
72+
# Output the new version
73+
Write-Output $newVersion

0 commit comments

Comments
 (0)