test-uv-app4 0.1.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.
- test_uv_app4-0.1.0/.env.example +17 -0
- test_uv_app4-0.1.0/.github/workflows/delete_workflow_runs.yml +72 -0
- test_uv_app4-0.1.0/.github/workflows/docs.yml +98 -0
- test_uv_app4-0.1.0/.github/workflows/release.yml +165 -0
- test_uv_app4-0.1.0/.github/workflows/tests.yml +55 -0
- test_uv_app4-0.1.0/.github/workflows/update_rtd.yml +69 -0
- test_uv_app4-0.1.0/.gitignore +49 -0
- test_uv_app4-0.1.0/.readthedocs.yaml +10 -0
- test_uv_app4-0.1.0/.vscode/launch.json +80 -0
- test_uv_app4-0.1.0/.vscode/settings.json +198 -0
- test_uv_app4-0.1.0/.vscode/tasks.json +19 -0
- test_uv_app4-0.1.0/CHANGELOG.md +16 -0
- test_uv_app4-0.1.0/CLAUDE.md +54 -0
- test_uv_app4-0.1.0/CredentialManagement.md +77 -0
- test_uv_app4-0.1.0/LICENSE +21 -0
- test_uv_app4-0.1.0/Makefile +354 -0
- test_uv_app4-0.1.0/PKG-INFO +55 -0
- test_uv_app4-0.1.0/README.md +42 -0
- test_uv_app4-0.1.0/RELEASE_NOTES.md +6 -0
- test_uv_app4-0.1.0/docs/Makefile +46 -0
- test_uv_app4-0.1.0/docs/_static/custom.css +0 -0
- test_uv_app4-0.1.0/docs/api/index.md +23 -0
- test_uv_app4-0.1.0/docs/api/modules.rst +7 -0
- test_uv_app4-0.1.0/docs/api/test_uv_app4.rst +21 -0
- test_uv_app4-0.1.0/docs/conf.py +176 -0
- test_uv_app4-0.1.0/docs/doc8.ini +6 -0
- test_uv_app4-0.1.0/docs/guides/index.md +14 -0
- test_uv_app4-0.1.0/docs/index.md +63 -0
- test_uv_app4-0.1.0/docs/post_gen_project.py +17 -0
- test_uv_app4-0.1.0/docs/requirements.txt +9 -0
- test_uv_app4-0.1.0/pyproject.toml +193 -0
- test_uv_app4-0.1.0/run.sh +790 -0
- test_uv_app4-0.1.0/scripts/release.py +771 -0
- test_uv_app4-0.1.0/scripts/update_versions.py +69 -0
- test_uv_app4-0.1.0/src/test_uv_app4/__init__.py +1 -0
- test_uv_app4-0.1.0/src/test_uv_app4/main.py +10 -0
- test_uv_app4-0.1.0/tests/__init__.py +0 -0
- test_uv_app4-0.1.0/tests/conftest.py +16 -0
- test_uv_app4-0.1.0/tests/test_test_uv_app4.py +16 -0
- test_uv_app4-0.1.0/uv.lock +2149 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# PyPI Publishing Tokens
|
|
2
|
+
# Copy this file to .env and add your actual tokens
|
|
3
|
+
# Get tokens from: https://pypi.org/manage/account/token/
|
|
4
|
+
|
|
5
|
+
# PyPI Token (for main pypi.org)
|
|
6
|
+
PYPI_TOKEN=
|
|
7
|
+
|
|
8
|
+
# TestPyPI Token (for test.pypi.org)
|
|
9
|
+
TEST_PYPI_TOKEN=
|
|
10
|
+
|
|
11
|
+
# ReadTheDocs Token (optional)
|
|
12
|
+
# Get from: https://readthedocs.org/accounts/tokens/
|
|
13
|
+
RTD_TOKEN=
|
|
14
|
+
|
|
15
|
+
# GitHub Token (optional, for gh CLI)
|
|
16
|
+
# Get from: https://github.com/settings/tokens
|
|
17
|
+
GITHUB_TOKEN=
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: Delete old workflow runs
|
|
2
|
+
on:
|
|
3
|
+
workflow_dispatch:
|
|
4
|
+
inputs:
|
|
5
|
+
days:
|
|
6
|
+
description: "Days to retain runs"
|
|
7
|
+
default: "30"
|
|
8
|
+
minimum_runs:
|
|
9
|
+
description: "Minimum runs to keep"
|
|
10
|
+
default: "6"
|
|
11
|
+
use_daily_retention:
|
|
12
|
+
description: "Enable daily retention (keep minimum runs per day instead of overall)"
|
|
13
|
+
default: "false"
|
|
14
|
+
type: choice
|
|
15
|
+
options:
|
|
16
|
+
- "false"
|
|
17
|
+
- "true"
|
|
18
|
+
delete_workflow_pattern:
|
|
19
|
+
description: "Workflow name or filename (omit for all). Use `|` to separate multiple filters (e.g. 'build|deploy')."
|
|
20
|
+
delete_workflow_by_state_pattern:
|
|
21
|
+
description: "Workflow state: active, deleted, disabled_fork, disabled_inactivity, disabled_manually"
|
|
22
|
+
default: "ALL"
|
|
23
|
+
type: choice
|
|
24
|
+
options:
|
|
25
|
+
- "ALL"
|
|
26
|
+
- active
|
|
27
|
+
- deleted
|
|
28
|
+
- disabled_inactivity
|
|
29
|
+
- disabled_manually
|
|
30
|
+
delete_run_by_conclusion_pattern:
|
|
31
|
+
description: "Run conclusion: action_required, cancelled, failure, skipped, success"
|
|
32
|
+
default: "ALL"
|
|
33
|
+
type: choice
|
|
34
|
+
options:
|
|
35
|
+
- "ALL"
|
|
36
|
+
- "Unsuccessful: action_required,cancelled,failure,skipped"
|
|
37
|
+
- action_required
|
|
38
|
+
- cancelled
|
|
39
|
+
- failure
|
|
40
|
+
- skipped
|
|
41
|
+
- success
|
|
42
|
+
dry_run:
|
|
43
|
+
description: "Simulate deletions"
|
|
44
|
+
default: "false"
|
|
45
|
+
type: choice
|
|
46
|
+
options:
|
|
47
|
+
- "false"
|
|
48
|
+
- "true"
|
|
49
|
+
jobs:
|
|
50
|
+
delete-runs:
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
permissions:
|
|
53
|
+
actions: write
|
|
54
|
+
contents: read
|
|
55
|
+
steps:
|
|
56
|
+
- name: Delete workflow runs
|
|
57
|
+
uses: Mattraks/delete-workflow-runs@v2
|
|
58
|
+
with:
|
|
59
|
+
token: ${{ github.token }}
|
|
60
|
+
repository: ${{ github.repository }}
|
|
61
|
+
retain_days: ${{ github.event.inputs.days }}
|
|
62
|
+
keep_minimum_runs: ${{ github.event.inputs.minimum_runs }}
|
|
63
|
+
use_daily_retention: ${{ github.event.inputs.use_daily_retention }}
|
|
64
|
+
delete_workflow_pattern: ${{ github.event.inputs.delete_workflow_pattern }}
|
|
65
|
+
delete_workflow_by_state_pattern: ${{ github.event.inputs.delete_workflow_by_state_pattern }}
|
|
66
|
+
delete_run_by_conclusion_pattern: >-
|
|
67
|
+
${{
|
|
68
|
+
startsWith(github.event.inputs.delete_run_by_conclusion_pattern, 'Unsuccessful:') &&
|
|
69
|
+
'action_required,cancelled,failure,skipped' ||
|
|
70
|
+
github.event.inputs.delete_run_by_conclusion_pattern
|
|
71
|
+
}}
|
|
72
|
+
dry_run: ${{ github.event.inputs.dry_run }}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
name: Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
paths:
|
|
8
|
+
- 'docs/**'
|
|
9
|
+
- '**/*.rst'
|
|
10
|
+
- '**/*.md'
|
|
11
|
+
- 'pyproject.toml'
|
|
12
|
+
- '.readthedocs.yaml'
|
|
13
|
+
pull_request:
|
|
14
|
+
branches:
|
|
15
|
+
- main
|
|
16
|
+
paths:
|
|
17
|
+
- 'docs/**'
|
|
18
|
+
- '**/*.rst'
|
|
19
|
+
- '**/*.md'
|
|
20
|
+
- 'pyproject.toml'
|
|
21
|
+
- '.readthedocs.yaml'
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
docs:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
- name: Set up Python
|
|
30
|
+
uses: actions/setup-python@v5
|
|
31
|
+
with:
|
|
32
|
+
python-version: '3.10'
|
|
33
|
+
|
|
34
|
+
- name: Install UV
|
|
35
|
+
uses: astral-sh/setup-uv@v5
|
|
36
|
+
|
|
37
|
+
- name: Cache UV dependencies
|
|
38
|
+
uses: actions/cache@v4
|
|
39
|
+
with:
|
|
40
|
+
path: .venv
|
|
41
|
+
key: ${{ runner.os }}-uv-${{ hashFiles('**/uv.lock', '**/pyproject.toml') }}
|
|
42
|
+
restore-keys: |
|
|
43
|
+
${{ runner.os }}-uv-
|
|
44
|
+
|
|
45
|
+
- name: Install Dependencies
|
|
46
|
+
run: |
|
|
47
|
+
uv sync --group docs
|
|
48
|
+
|
|
49
|
+
- name: Check Documentation Quality
|
|
50
|
+
run: |
|
|
51
|
+
cd docs
|
|
52
|
+
uv run doc8 . || echo "Documentation quality check found issues"
|
|
53
|
+
uv run make linkcheck || echo "Link check found broken links"
|
|
54
|
+
continue-on-error: true
|
|
55
|
+
|
|
56
|
+
- name: Build Documentation
|
|
57
|
+
run: |
|
|
58
|
+
cd docs
|
|
59
|
+
uv run make SPHINXOPTS="-v" html
|
|
60
|
+
env:
|
|
61
|
+
PYTHONPATH: ${{ github.workspace }}/src
|
|
62
|
+
SPHINX_DEBUG: 1
|
|
63
|
+
|
|
64
|
+
- name: Check Build Output
|
|
65
|
+
if: always()
|
|
66
|
+
run: |
|
|
67
|
+
echo "Checking docs build directory..."
|
|
68
|
+
cd docs/_build/html
|
|
69
|
+
ls -la
|
|
70
|
+
if [ -f "index.html" ]; then
|
|
71
|
+
echo "Documentation built successfully"
|
|
72
|
+
else
|
|
73
|
+
echo "Documentation build failed - no index.html"
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
- name: Upload Documentation Artifacts
|
|
78
|
+
if: always()
|
|
79
|
+
uses: actions/upload-artifact@v4
|
|
80
|
+
with:
|
|
81
|
+
name: documentation
|
|
82
|
+
path: docs/_build/html/
|
|
83
|
+
compression-level: 0
|
|
84
|
+
|
|
85
|
+
- name: Comment PR with documentation preview
|
|
86
|
+
if: github.event_name == 'pull_request' && success()
|
|
87
|
+
uses: actions/github-script@v7
|
|
88
|
+
with:
|
|
89
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
90
|
+
script: |
|
|
91
|
+
const artifactUrl = 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}';
|
|
92
|
+
const body = '📚 Documentation preview is available! [Download the artifact](' + artifactUrl + ') and view locally.';
|
|
93
|
+
github.rest.issues.createComment({
|
|
94
|
+
issue_number: context.issue.number,
|
|
95
|
+
owner: context.repo.owner,
|
|
96
|
+
repo: context.repo.repo,
|
|
97
|
+
body: body
|
|
98
|
+
});
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ['v*']
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: write
|
|
9
|
+
id-token: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
|
|
13
|
+
tests:
|
|
14
|
+
uses: ./.github/workflows/tests.yml
|
|
15
|
+
|
|
16
|
+
release:
|
|
17
|
+
needs: tests
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
permissions:
|
|
20
|
+
contents: write
|
|
21
|
+
id-token: write
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0
|
|
26
|
+
|
|
27
|
+
- name: Set up Python
|
|
28
|
+
uses: actions/setup-python@v5
|
|
29
|
+
with:
|
|
30
|
+
python-version: '3.10'
|
|
31
|
+
|
|
32
|
+
- name: Install UV
|
|
33
|
+
uses: astral-sh/setup-uv@v5
|
|
34
|
+
|
|
35
|
+
- name: Cache UV dependencies
|
|
36
|
+
uses: actions/cache@v4
|
|
37
|
+
with:
|
|
38
|
+
path: .venv
|
|
39
|
+
key: ${{ runner.os }}-uv-${{ hashFiles('**/uv.lock', '**/pyproject.toml') }}
|
|
40
|
+
restore-keys: |
|
|
41
|
+
${{ runner.os }}-uv-
|
|
42
|
+
|
|
43
|
+
- name: Determine release type and latest status
|
|
44
|
+
id: release-info
|
|
45
|
+
run: |
|
|
46
|
+
TAG_NAME=${{ github.ref_name }}
|
|
47
|
+
VERSION=${TAG_NAME#v}
|
|
48
|
+
|
|
49
|
+
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
|
|
50
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
51
|
+
|
|
52
|
+
# Determine if this should be marked as latest
|
|
53
|
+
# Latest = stable releases (x.y.z) and post releases (x.y.z.postN)
|
|
54
|
+
if [[ $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+(\.(post)[0-9]+)?$ ]]; then
|
|
55
|
+
echo "is_latest=true" >> $GITHUB_OUTPUT
|
|
56
|
+
echo "release_type=release" >> $GITHUB_OUTPUT
|
|
57
|
+
echo "📦 Stable release - will be marked as latest"
|
|
58
|
+
elif [[ $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+[-\.]?(a|alpha|b|beta|rc)[0-9]*$ ]]; then
|
|
59
|
+
echo "is_latest=false" >> $GITHUB_OUTPUT
|
|
60
|
+
echo "release_type=prerelease" >> $GITHUB_OUTPUT
|
|
61
|
+
echo "🧪 Pre-release - will NOT be marked as latest"
|
|
62
|
+
elif [[ $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+[-\.]?(dev)[0-9]*$ ]]; then
|
|
63
|
+
echo "is_latest=false" >> $GITHUB_OUTPUT
|
|
64
|
+
echo "release_type=dev" >> $GITHUB_OUTPUT
|
|
65
|
+
echo "🚧 Development release - will NOT be marked as latest"
|
|
66
|
+
else
|
|
67
|
+
echo "is_latest=false" >> $GITHUB_OUTPUT
|
|
68
|
+
echo "release_type=draft" >> $GITHUB_OUTPUT
|
|
69
|
+
echo "📝 Draft release - will NOT be marked as latest"
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
- name: Extract release notes from tag
|
|
73
|
+
id: release-notes
|
|
74
|
+
run: |
|
|
75
|
+
VERSION=${{ steps.release-info.outputs.version }}
|
|
76
|
+
TAG_NAME=${{ steps.release-info.outputs.tag_name }}
|
|
77
|
+
|
|
78
|
+
echo "Extracting message from tag $TAG_NAME..."
|
|
79
|
+
git tag -l --format='%(contents)' "$TAG_NAME" > RELEASE_NOTES.md
|
|
80
|
+
|
|
81
|
+
if [ ! -s RELEASE_NOTES.md ]; then
|
|
82
|
+
echo "Warning: Could not extract tag message for $TAG_NAME"
|
|
83
|
+
echo "Creating simple release notes..."
|
|
84
|
+
echo "# Release $TAG_NAME" > RELEASE_NOTES.md
|
|
85
|
+
echo "" >> RELEASE_NOTES.md
|
|
86
|
+
echo "See CHANGELOG.md for details." >> RELEASE_NOTES.md
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
echo "Release notes content:"
|
|
90
|
+
cat RELEASE_NOTES.md
|
|
91
|
+
|
|
92
|
+
- name: Build package
|
|
93
|
+
run: ./run.sh build
|
|
94
|
+
|
|
95
|
+
# Always test on TestPyPI first
|
|
96
|
+
- name: Test PyPI release
|
|
97
|
+
env:
|
|
98
|
+
TEST_PYPI_TOKEN: ${{ secrets.TEST_PYPI_TOKEN }}
|
|
99
|
+
run: ./run.sh publish:test:strict
|
|
100
|
+
|
|
101
|
+
- name: Test installation from TestPyPI
|
|
102
|
+
run: |
|
|
103
|
+
python -m venv test_env
|
|
104
|
+
source test_env/bin/activate
|
|
105
|
+
pip install --index-url https://test.pypi.org/simple/ \
|
|
106
|
+
--extra-index-url https://pypi.org/simple \
|
|
107
|
+
test-uv-app4
|
|
108
|
+
SITE_PACKAGES=$(python -c "import site; print(site.getsitepackages()[0])")
|
|
109
|
+
export PYTHONPATH="${SITE_PACKAGES}:${PYTHONPATH:-}"
|
|
110
|
+
python -c "import test_uv_app4; print('Installed version: ' + test_uv_app4.__version__)"
|
|
111
|
+
|
|
112
|
+
- name: Create GitHub Release
|
|
113
|
+
uses: softprops/action-gh-release@v2
|
|
114
|
+
with:
|
|
115
|
+
files: dist/*
|
|
116
|
+
body_path: RELEASE_NOTES.md
|
|
117
|
+
# Key improvement: Control latest tag assignment
|
|
118
|
+
make_latest: ${{ steps.release-info.outputs.is_latest }}
|
|
119
|
+
prerelease: ${{ steps.release-info.outputs.release_type == 'prerelease' || steps.release-info.outputs.release_type == 'dev' }}
|
|
120
|
+
draft: ${{ steps.release-info.outputs.release_type == 'draft' }}
|
|
121
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
122
|
+
|
|
123
|
+
# Only publish stable releases to PyPI
|
|
124
|
+
- name: Publish to PyPI
|
|
125
|
+
if: steps.release-info.outputs.release_type == 'release'
|
|
126
|
+
env:
|
|
127
|
+
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
|
128
|
+
run: ./run.sh publish:strict
|
|
129
|
+
|
|
130
|
+
# Update ReadTheDocs for all tagged versions
|
|
131
|
+
# Note: Set RTD default version to "stable" in project settings for best UX
|
|
132
|
+
- name: Update ReadTheDocs
|
|
133
|
+
run: |
|
|
134
|
+
TAG_NAME=${{ steps.release-info.outputs.tag_name }}
|
|
135
|
+
echo "Activating version $TAG_NAME via API..."
|
|
136
|
+
for i in 1 2 3 4 5; do
|
|
137
|
+
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -X PATCH \
|
|
138
|
+
-H "Authorization: Token ${{ secrets.RTD_TOKEN }}" \
|
|
139
|
+
-H "Content-Type: application/json" \
|
|
140
|
+
-d '{"active": true}' \
|
|
141
|
+
"https://readthedocs.org/api/v3/projects/test-uv-app4/versions/$TAG_NAME/")
|
|
142
|
+
if [ "$RESPONSE" = "204" ]; then
|
|
143
|
+
echo "Successfully activated version $TAG_NAME"
|
|
144
|
+
break
|
|
145
|
+
fi
|
|
146
|
+
echo "Attempt $i: RTD returned HTTP $RESPONSE, retrying in 15s..."
|
|
147
|
+
sleep 15
|
|
148
|
+
done
|
|
149
|
+
if [ "$RESPONSE" != "204" ]; then
|
|
150
|
+
echo "Warning: Failed to activate $TAG_NAME after 5 attempts (last HTTP $RESPONSE)"
|
|
151
|
+
fi
|
|
152
|
+
continue-on-error: true
|
|
153
|
+
|
|
154
|
+
- name: Release Summary
|
|
155
|
+
run: |
|
|
156
|
+
echo "## 🚀 Release Summary" >> $GITHUB_STEP_SUMMARY
|
|
157
|
+
echo "- **Version**: ${{ steps.release-info.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
|
158
|
+
echo "- **Type**: ${{ steps.release-info.outputs.release_type }}" >> $GITHUB_STEP_SUMMARY
|
|
159
|
+
echo "- **Latest**: ${{ steps.release-info.outputs.is_latest }}" >> $GITHUB_STEP_SUMMARY
|
|
160
|
+
echo "- **ReadTheDocs**: ✅ Updated" >> $GITHUB_STEP_SUMMARY
|
|
161
|
+
if [[ "${{ steps.release-info.outputs.release_type }}" == "release" ]]; then
|
|
162
|
+
echo "- **PyPI**: ✅ Published" >> $GITHUB_STEP_SUMMARY
|
|
163
|
+
else
|
|
164
|
+
echo "- **PyPI**: ⏭️ Skipped (not a stable release)" >> $GITHUB_STEP_SUMMARY
|
|
165
|
+
fi
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# This workflow was inspired by Eric Riddoch's "built-test-publish.yaml"
|
|
2
|
+
# but has been fully re-implemented and adapted for this project.
|
|
3
|
+
|
|
4
|
+
name: Tests
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
workflow_call:
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
pull_request:
|
|
10
|
+
push:
|
|
11
|
+
branches: [main]
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
tests:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
matrix:
|
|
18
|
+
python-version: ["3.10"]
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
24
|
+
uses: actions/setup-python@v5
|
|
25
|
+
with:
|
|
26
|
+
python-version: ${{ matrix.python-version }}
|
|
27
|
+
|
|
28
|
+
- name: Install UV
|
|
29
|
+
uses: astral-sh/setup-uv@v5
|
|
30
|
+
|
|
31
|
+
- name: Cache UV dependencies
|
|
32
|
+
uses: actions/cache@v4
|
|
33
|
+
with:
|
|
34
|
+
path: .venv
|
|
35
|
+
key: ${{ runner.os }}-uv-${{ hashFiles('**/uv.lock', '**/pyproject.toml') }}
|
|
36
|
+
restore-keys: |
|
|
37
|
+
${{ runner.os }}-uv-
|
|
38
|
+
|
|
39
|
+
- name: Install dependencies
|
|
40
|
+
run: ./run.sh install:all
|
|
41
|
+
|
|
42
|
+
- name: Check code formatting with black
|
|
43
|
+
run: ./run.sh format:check:black
|
|
44
|
+
|
|
45
|
+
- name: Check import sorting with isort
|
|
46
|
+
run: ./run.sh format:check:isort
|
|
47
|
+
|
|
48
|
+
- name: Run type checking with mypy
|
|
49
|
+
run: ./run.sh lint:mypy
|
|
50
|
+
|
|
51
|
+
- name: Run linting with flake8
|
|
52
|
+
run: ./run.sh lint:flake8
|
|
53
|
+
|
|
54
|
+
- name: Run tests
|
|
55
|
+
run: ./run.sh tests || [ $? -eq 5 ]
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
name: Update ReadTheDocs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
version:
|
|
7
|
+
description: 'Version to update on ReadTheDocs'
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
update_rtd:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- name: Checkout code
|
|
16
|
+
uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
fetch-depth: 0
|
|
19
|
+
|
|
20
|
+
- name: List all versions on ReadTheDocs
|
|
21
|
+
run: |
|
|
22
|
+
echo "Listing all versions on ReadTheDocs..."
|
|
23
|
+
curl -s \
|
|
24
|
+
-H "Authorization: Token ${{ secrets.RTD_TOKEN }}" \
|
|
25
|
+
"https://readthedocs.org/api/v3/projects/test-uv-app4/versions/" | jq
|
|
26
|
+
|
|
27
|
+
- name: Create tag if needed
|
|
28
|
+
run: |
|
|
29
|
+
TAG="v${{ github.event.inputs.version }}"
|
|
30
|
+
if ! git tag -l | grep -q "^$TAG$"; then
|
|
31
|
+
echo "Tag $TAG doesn't exist locally. Creating it..."
|
|
32
|
+
git tag $TAG
|
|
33
|
+
git push origin $TAG
|
|
34
|
+
echo "Tag $TAG created and pushed."
|
|
35
|
+
else
|
|
36
|
+
echo "Tag $TAG already exists."
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
- name: Sync versions
|
|
40
|
+
run: |
|
|
41
|
+
echo "Syncing versions with ReadTheDocs..."
|
|
42
|
+
curl -X POST \
|
|
43
|
+
-H "Authorization: Token ${{ secrets.RTD_TOKEN }}" \
|
|
44
|
+
-H "Content-Type: application/json" \
|
|
45
|
+
"https://readthedocs.org/api/v3/projects/test-uv-app4/sync/"
|
|
46
|
+
|
|
47
|
+
- name: Wait for sync to complete
|
|
48
|
+
run: sleep 20
|
|
49
|
+
|
|
50
|
+
- name: Active version
|
|
51
|
+
run: |
|
|
52
|
+
echo "Activating version v${{ github.event.inputs.version }}"
|
|
53
|
+
curl -X PATCH \
|
|
54
|
+
-H "Authorization: Token ${{ secrets.RTD_TOKEN }}" \
|
|
55
|
+
-H "Content-Type: application/json" \
|
|
56
|
+
-d '{"active": true}' \
|
|
57
|
+
"https://readthedocs.org/api/v3/projects/test-uv-app4/versions/v${{ github.event.inputs.version }}/"
|
|
58
|
+
|
|
59
|
+
- name: Trigger build
|
|
60
|
+
run: |
|
|
61
|
+
echo "Triggering build for version ${{ github.event.inputs.version }}..."
|
|
62
|
+
curl -X POST \
|
|
63
|
+
-H "Authorization: Token ${{ secrets.RTD_TOKEN }}" \
|
|
64
|
+
-H "Content-Type: application/json" \
|
|
65
|
+
"https://readthedocs.org/api/v3/projects/test-uv-app4/versions/v${{ github.event.inputs.version }}/builds/"
|
|
66
|
+
|
|
67
|
+
- name: Check build status
|
|
68
|
+
run: |
|
|
69
|
+
echo "View builds at https://readthedocs.org/projects/test-uv-app4/builds/"
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Secrets
|
|
2
|
+
.pypirc
|
|
3
|
+
.env
|
|
4
|
+
|
|
5
|
+
# Compiled and Cached Files
|
|
6
|
+
__pycache__/
|
|
7
|
+
.mypy_cache/
|
|
8
|
+
.mypy_cache_test/
|
|
9
|
+
.mypy_cache_diff/
|
|
10
|
+
.ipynb_checkpoints/
|
|
11
|
+
.pytest_cache
|
|
12
|
+
|
|
13
|
+
# Distribution / packaging
|
|
14
|
+
build/
|
|
15
|
+
dist/
|
|
16
|
+
*.egg-info/
|
|
17
|
+
|
|
18
|
+
# Logs
|
|
19
|
+
*.log
|
|
20
|
+
|
|
21
|
+
# Documentation
|
|
22
|
+
docs/_build/
|
|
23
|
+
|
|
24
|
+
# Test and Coverage
|
|
25
|
+
htmlcov/
|
|
26
|
+
.coverage
|
|
27
|
+
coverage.xml
|
|
28
|
+
|
|
29
|
+
# VS Code
|
|
30
|
+
.vscode/*
|
|
31
|
+
!.vscode/settings.json
|
|
32
|
+
!.vscode/tasks.json
|
|
33
|
+
!.vscode/launch.json
|
|
34
|
+
!.vscode/extensions.json
|
|
35
|
+
*.code-workspace
|
|
36
|
+
|
|
37
|
+
# Claude
|
|
38
|
+
.claude/*
|
|
39
|
+
|
|
40
|
+
# Environment
|
|
41
|
+
.venv
|
|
42
|
+
env/
|
|
43
|
+
venv/
|
|
44
|
+
ENV/
|
|
45
|
+
|
|
46
|
+
# Misc
|
|
47
|
+
.DS_Store
|
|
48
|
+
*.pkl
|
|
49
|
+
*.pickle
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.2.0",
|
|
3
|
+
"configurations": [
|
|
4
|
+
{
|
|
5
|
+
"name": "Debug Prolog Files",
|
|
6
|
+
"type": "prolog",
|
|
7
|
+
"request": "launch",
|
|
8
|
+
"runtimeExecutable": "/opt/homebrew/bin/swipl",
|
|
9
|
+
"runtimeArgs": [
|
|
10
|
+
"-s", "${file}",
|
|
11
|
+
"-g", "start",
|
|
12
|
+
"-t", "halt",
|
|
13
|
+
"-q",
|
|
14
|
+
],
|
|
15
|
+
"env": {},
|
|
16
|
+
"program": "${file}",
|
|
17
|
+
"cwd": "${fileDirname}",
|
|
18
|
+
"startupQuery": "main",
|
|
19
|
+
"stopOnEntry": true,
|
|
20
|
+
"traceCmds": {
|
|
21
|
+
"continue": ["leap", "l"],
|
|
22
|
+
"stepover": ["skip", "s"],
|
|
23
|
+
"stepinto": ["creep", "c"],
|
|
24
|
+
"stepout": ["up", "u"]
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "Run Prolog Files",
|
|
29
|
+
"type": "prolog",
|
|
30
|
+
"request": "launch",
|
|
31
|
+
"runtimeExecutable": "/opt/homebrew/bin/swipl",
|
|
32
|
+
"runtimeArgs": [
|
|
33
|
+
"-s", "${file}",
|
|
34
|
+
"-g", "main",
|
|
35
|
+
"-t", "halt",
|
|
36
|
+
|
|
37
|
+
],
|
|
38
|
+
"env": {},
|
|
39
|
+
"program": "${file}",
|
|
40
|
+
"cwd": "${fileDirname}",
|
|
41
|
+
"stopOnEntry": false,
|
|
42
|
+
"startupQuery": "main",
|
|
43
|
+
"traceCmds": {
|
|
44
|
+
"continue": ["leap", "l"],
|
|
45
|
+
"stepover": ["skip", "s"],
|
|
46
|
+
"stepinto": ["creep", "c"],
|
|
47
|
+
"stepout": ["up", "u"]
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "Python with Prolog",
|
|
52
|
+
"type": "debugpy",
|
|
53
|
+
"request": "launch",
|
|
54
|
+
"program": "${file}",
|
|
55
|
+
"console": "integratedTerminal",
|
|
56
|
+
"justMyCode": true,
|
|
57
|
+
"env": {
|
|
58
|
+
"PYTHONPATH": "${workspaceFolder}/src:${PYTHONPATH}",
|
|
59
|
+
"DYLD_LIBRARY_PATH": "/opt/homebrew/Cellar/swi-prolog/9.2.8/lib/swipl/lib/arm64-darwin:/opt/homebrew/Cellar/swi-prolog/9.2.8/lib/Frameworks",
|
|
60
|
+
"SWI_HOME_DIR": "/opt/homebrew/Cellar/swi-prolog/9.2.8/lib/swipl"
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": "Python (Regular)",
|
|
65
|
+
"type": "debugpy",
|
|
66
|
+
"request": "launch",
|
|
67
|
+
"program": "${file}",
|
|
68
|
+
"console": "integratedTerminal",
|
|
69
|
+
"justMyCode": true
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "Python Main",
|
|
73
|
+
"type": "debugpy",
|
|
74
|
+
"request": "launch",
|
|
75
|
+
"program": "${workspaceFolder}/main.py",
|
|
76
|
+
"console": "integratedTerminal",
|
|
77
|
+
"justMyCode": true
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}
|