ezcompiler 2.3.4__tar.gz → 2.4.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.
- ezcompiler-2.4.0/.github/workflows/auto-tag.yml +110 -0
- ezcompiler-2.4.0/.github/workflows/ci-usage.md +76 -0
- ezcompiler-2.4.0/.github/workflows/ci.yml +89 -0
- ezcompiler-2.4.0/.github/workflows/docs-usage.md +91 -0
- ezcompiler-2.4.0/.github/workflows/docs.yml +84 -0
- ezcompiler-2.4.0/.github/workflows/publish-pypi-usage.md +97 -0
- ezcompiler-2.4.0/.github/workflows/publish-pypi.yml +121 -0
- ezcompiler-2.4.0/.markdownlint.yaml +38 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/.pre-commit-config.yaml +40 -41
- ezcompiler-2.4.0/.scripts/dev/check_merge_conflict.py +33 -0
- ezcompiler-2.4.0/.scripts/dev/check_toml.py +26 -0
- ezcompiler-2.4.0/.scripts/dev/check_yaml.py +33 -0
- ezcompiler-2.4.0/AGENTS.md +149 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/PKG-INFO +36 -18
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/README.md +19 -11
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/mkdocs.yml +17 -3
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/pyproject.toml +20 -10
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/_version.py +1 -1
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/adapters/_pyinstaller_compiler.py +3 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/adapters/base_compiler.py +4 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/adapters/base_uploader.py +2 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/adapters/compiler_factory.py +43 -4
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/interfaces/cli_interface.py +7 -4
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/interfaces/python_api.py +10 -4
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/services/compiler_service.py +2 -2
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/services/pipeline_service.py +6 -3
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/_compilation_result.py +2 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/exceptions/services/_base.py +4 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/_compiler_utils.py +3 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/_zip_utils.py +4 -6
- ezcompiler-2.4.0/uv.lock +1823 -0
- ezcompiler-2.4.0/uv.toml +3 -0
- ezcompiler-2.3.4/.clinerules +0 -29
- ezcompiler-2.3.4/.github/instructions/README.md +0 -1015
- ezcompiler-2.3.4/.github/instructions/core/advanced-cognitive-conduct.instructions.md +0 -299
- ezcompiler-2.3.4/.github/instructions/core/commit-standards.instructions.md +0 -139
- ezcompiler-2.3.4/.github/instructions/core/hexagonal-architecture-standards.instructions.md +0 -601
- ezcompiler-2.3.4/.github/instructions/languages/python/pyproject-standards.instructions.md +0 -402
- ezcompiler-2.3.4/.github/instructions/languages/python/python-development-standards.instructions.md +0 -347
- ezcompiler-2.3.4/.github/instructions/languages/python/python-formatting-standards.instructions.md +0 -419
- ezcompiler-2.3.4/.github/workflows/README_DOC.md +0 -492
- ezcompiler-2.3.4/.github/workflows/README_PUBLISH.md +0 -301
- ezcompiler-2.3.4/.github/workflows/auto-tag.yml +0 -206
- ezcompiler-2.3.4/.github/workflows/docs.yml +0 -80
- ezcompiler-2.3.4/.github/workflows/publish-pypi.yml +0 -182
- ezcompiler-2.3.4/AGENTS.md +0 -87
- ezcompiler-2.3.4/CLAUDE.md +0 -98
- ezcompiler-2.3.4/uv.lock +0 -2048
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/.gitignore +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/.scripts/build/build_package.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/.scripts/build/upload_to_pypi.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/.scripts/dev/generate_architecture_graph.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/.scripts/dev/lint.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/.scripts/dev/update_version.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/LICENSE +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/MANIFEST.in +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/cliff.toml +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/herald.config.json +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/requirements-dev.in +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/requirements.in +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/__init__.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/adapters/__init__.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/adapters/_cx_freeze_compiler.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/adapters/_disk_file_writer.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/adapters/_disk_uploader.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/adapters/_nuitka_compiler.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/adapters/_server_uploader.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/adapters/base_file_writer.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/adapters/uploader_factory.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/assets/__init__.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/assets/templates/__init__.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/assets/templates/_template_loader.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/assets/templates/config/config.json.template +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/assets/templates/config/config.yaml.template +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/assets/templates/setup/setup.py.template +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/assets/templates/version/version_info.txt.template +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/interfaces/__init__.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/py.typed +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/services/__init__.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/services/config_service.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/services/template_service.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/services/uploader_service.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/__init__.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/_compiler_config.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/exceptions/__init__.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/exceptions/services/__init__.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/exceptions/services/_service_exceptions.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/exceptions/utils/__init__.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/exceptions/utils/_base.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/exceptions/utils/_compiler_exceptions.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/exceptions/utils/_config_exceptions.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/exceptions/utils/_file_exceptions.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/exceptions/utils/_template_exceptions.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/exceptions/utils/_uploader_exceptions.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/exceptions/utils/_validation_exceptions.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/shared/exceptions/utils/_zip_exceptions.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/types.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/__init__.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/_config_utils.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/_file_utils.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/_template_utils.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/_uploader_utils.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/validators/__init__.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/validators/domain_validators.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/validators/format_validators.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/validators/meta_validators.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/validators/path_validators.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/validators/schema_validators.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/validators/string_validators.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/validators/type_validators.py +0 -0
- {ezcompiler-2.3.4 → ezcompiler-2.4.0}/src/ezcompiler/utils/validators/value_validators.py +0 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
name: Auto Tag
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions: {}
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: auto-tag-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: false
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
auto-tag:
|
|
16
|
+
name: Create and Push Tags
|
|
17
|
+
runs-on: ubuntu-24.04
|
|
18
|
+
permissions:
|
|
19
|
+
contents: write
|
|
20
|
+
outputs:
|
|
21
|
+
tag_action: ${{ steps.create_tags.outputs.tag_action }}
|
|
22
|
+
version: ${{ steps.version.outputs.version }}
|
|
23
|
+
tag_name: ${{ steps.create_tags.outputs.tag_name }}
|
|
24
|
+
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@9f698171ed81b15d1823a05fc7211befd50c8ae0 # v6.0.3
|
|
27
|
+
with:
|
|
28
|
+
fetch-depth: 0
|
|
29
|
+
|
|
30
|
+
- name: Extract version from pyproject.toml
|
|
31
|
+
id: version
|
|
32
|
+
run: |
|
|
33
|
+
VERSION=$(grep -E '^version\s*=\s*"' pyproject.toml | head -1 | sed 's/.*version\s*=\s*"\([^"]*\)".*/\1/')
|
|
34
|
+
if [ -z "$VERSION" ]; then
|
|
35
|
+
echo "::error::No version found in pyproject.toml"
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
39
|
+
echo "Version: $VERSION"
|
|
40
|
+
|
|
41
|
+
- name: Create and push tags
|
|
42
|
+
id: create_tags
|
|
43
|
+
run: |
|
|
44
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
45
|
+
TAG_NAME="v$VERSION"
|
|
46
|
+
MAJOR=$(echo "$VERSION" | cut -d. -f1)
|
|
47
|
+
LATEST_TAG="v${MAJOR}-latest"
|
|
48
|
+
|
|
49
|
+
git config user.name "github-actions[bot]"
|
|
50
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
51
|
+
|
|
52
|
+
if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then
|
|
53
|
+
TAG_SHA=$(git rev-parse "$TAG_NAME")
|
|
54
|
+
HEAD_SHA=$(git rev-parse HEAD)
|
|
55
|
+
if [ "$TAG_SHA" = "$HEAD_SHA" ]; then
|
|
56
|
+
echo "tag_action=none" >> $GITHUB_OUTPUT
|
|
57
|
+
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
|
|
58
|
+
echo "Tag $TAG_NAME already points to HEAD — nothing to do"
|
|
59
|
+
else
|
|
60
|
+
git tag -f "$TAG_NAME"
|
|
61
|
+
git tag -f "$LATEST_TAG"
|
|
62
|
+
git push origin --force "$TAG_NAME"
|
|
63
|
+
git push origin --force "$LATEST_TAG"
|
|
64
|
+
echo "tag_action=update" >> $GITHUB_OUTPUT
|
|
65
|
+
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
|
|
66
|
+
echo "🔄 Tags moved to HEAD: $TAG_NAME, $LATEST_TAG (no publish — version unchanged)"
|
|
67
|
+
fi
|
|
68
|
+
else
|
|
69
|
+
git tag "$TAG_NAME"
|
|
70
|
+
git tag -f "$LATEST_TAG"
|
|
71
|
+
git push origin "$TAG_NAME"
|
|
72
|
+
git push origin --force "$LATEST_TAG"
|
|
73
|
+
echo "tag_action=create" >> $GITHUB_OUTPUT
|
|
74
|
+
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
|
|
75
|
+
echo "✅ Tags pushed: $TAG_NAME, $LATEST_TAG"
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
- name: Summary
|
|
79
|
+
if: steps.create_tags.outputs.tag_action != 'none'
|
|
80
|
+
run: |
|
|
81
|
+
echo "## 🏷️ Auto-Tagging Summary" >> $GITHUB_STEP_SUMMARY
|
|
82
|
+
echo "- **Action**: ${{ steps.create_tags.outputs.tag_action }}" >> $GITHUB_STEP_SUMMARY
|
|
83
|
+
echo "- **Version**: ${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
|
84
|
+
echo "- **Tag**: ${{ steps.create_tags.outputs.tag_name }}" >> $GITHUB_STEP_SUMMARY
|
|
85
|
+
|
|
86
|
+
trigger-publish:
|
|
87
|
+
name: Trigger Publish
|
|
88
|
+
needs: auto-tag
|
|
89
|
+
if: needs.auto-tag.outputs.tag_action == 'create'
|
|
90
|
+
permissions:
|
|
91
|
+
contents: read
|
|
92
|
+
id-token: write
|
|
93
|
+
uses: ./.github/workflows/publish-pypi.yml
|
|
94
|
+
with:
|
|
95
|
+
version: ${{ needs.auto-tag.outputs.version }}
|
|
96
|
+
tag: ${{ needs.auto-tag.outputs.tag_name }}
|
|
97
|
+
|
|
98
|
+
trigger-deploy-docs:
|
|
99
|
+
name: Trigger Deploy Docs
|
|
100
|
+
needs: [auto-tag, trigger-publish]
|
|
101
|
+
if: |
|
|
102
|
+
always() &&
|
|
103
|
+
needs.auto-tag.result == 'success' &&
|
|
104
|
+
needs.auto-tag.outputs.tag_action != 'none' &&
|
|
105
|
+
(needs.trigger-publish.result == 'success' || needs.trigger-publish.result == 'skipped')
|
|
106
|
+
permissions:
|
|
107
|
+
contents: write
|
|
108
|
+
uses: ./.github/workflows/docs.yml
|
|
109
|
+
with:
|
|
110
|
+
deploy: true
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# CI Workflow
|
|
2
|
+
|
|
3
|
+
`ci.yml` runs on every push (all branches), every pull request, and manually via
|
|
4
|
+
`workflow_dispatch`. It is the primary quality gate — release workflows never run
|
|
5
|
+
if this one is red.
|
|
6
|
+
|
|
7
|
+
## Triggers
|
|
8
|
+
|
|
9
|
+
| Event | Branches |
|
|
10
|
+
| ------------------- | -------- |
|
|
11
|
+
| `push` | all |
|
|
12
|
+
| `pull_request` | all |
|
|
13
|
+
| `workflow_dispatch` | manual |
|
|
14
|
+
|
|
15
|
+
Concurrent runs on the same ref are cancelled automatically (`cancel-in-progress: true`,
|
|
16
|
+
group `ci-$ref`). Deploy jobs are never affected because they live in separate workflows.
|
|
17
|
+
|
|
18
|
+
## Jobs
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
lint ──┐
|
|
22
|
+
├──► test (Python 3.13)
|
|
23
|
+
type-check ──┘
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`lint` and `type-check` run in parallel; `test` needs both.
|
|
27
|
+
|
|
28
|
+
### `lint` — Lint & Format Check
|
|
29
|
+
|
|
30
|
+
Timeout: 15 min. Steps:
|
|
31
|
+
|
|
32
|
+
1. `uv sync --frozen --extra dev`
|
|
33
|
+
2. `ruff check .` — lint
|
|
34
|
+
3. `ruff format --check .` — format check (read-only, never auto-fixes)
|
|
35
|
+
|
|
36
|
+
### `type-check` — Type Check & Import Contracts
|
|
37
|
+
|
|
38
|
+
Timeout: 15 min. Steps:
|
|
39
|
+
|
|
40
|
+
1. `uv sync --frozen --extra dev`
|
|
41
|
+
2. `uv run ty check` — type check (configured via `[tool.ty]` in `pyproject.toml`)
|
|
42
|
+
3. `uv run pyright` — type check complémentaire (configured via `[tool.pyright]`)
|
|
43
|
+
4. `PYTHONPATH=src uv run lint-imports` — import-linter contracts (couches hexagonales)
|
|
44
|
+
|
|
45
|
+
### `test` — pytest
|
|
46
|
+
|
|
47
|
+
Needs: `[lint, type-check]`. Timeout: 25 min. Python **3.13 only** (`fail-fast: false`).
|
|
48
|
+
|
|
49
|
+
Steps:
|
|
50
|
+
|
|
51
|
+
1. `uv sync --frozen --extra dev`
|
|
52
|
+
2. `uv run pytest` — reads `pyproject.toml`, applies `--cov-fail-under=70`
|
|
53
|
+
3. Upload `coverage.xml` + `htmlcov/` as artifact — **always** (even on failure), retained 7 days
|
|
54
|
+
|
|
55
|
+
## Local equivalent
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Quality gate
|
|
59
|
+
uv run ruff check .
|
|
60
|
+
uv run ruff format --check .
|
|
61
|
+
uv run ty check
|
|
62
|
+
uv run pyright
|
|
63
|
+
PYTHONPATH=src uv run lint-imports
|
|
64
|
+
|
|
65
|
+
# Tests
|
|
66
|
+
uv run pytest
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Notes
|
|
70
|
+
|
|
71
|
+
- The install is always frozen (`uv sync --frozen`). Never mutates `uv.lock`.
|
|
72
|
+
- `ruff check` and `ruff format --check` are read-only — they never auto-fix.
|
|
73
|
+
- Both `ty` and `pyright` are configured in `pyproject.toml` and run in CI.
|
|
74
|
+
- Import contracts are enforced by import-linter against the hexagonal layer
|
|
75
|
+
contracts defined in `[tool.importlinter]`. Adding a cross-layer import
|
|
76
|
+
without updating the contracts will fail this job.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
# Runs on every push to main and on pull requests.
|
|
4
|
+
# Quality gates (lint, type-check) run first and block the test matrix.
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [main]
|
|
9
|
+
paths:
|
|
10
|
+
- "src/**"
|
|
11
|
+
- "tests/**"
|
|
12
|
+
- "pyproject.toml"
|
|
13
|
+
- "uv.lock"
|
|
14
|
+
- ".github/workflows/ci.yml"
|
|
15
|
+
pull_request:
|
|
16
|
+
branches: [main]
|
|
17
|
+
paths:
|
|
18
|
+
- "src/**"
|
|
19
|
+
- "tests/**"
|
|
20
|
+
- "pyproject.toml"
|
|
21
|
+
- "uv.lock"
|
|
22
|
+
- ".github/workflows/ci.yml"
|
|
23
|
+
workflow_dispatch:
|
|
24
|
+
|
|
25
|
+
permissions: {}
|
|
26
|
+
|
|
27
|
+
concurrency:
|
|
28
|
+
group: ci-${{ github.ref }}
|
|
29
|
+
cancel-in-progress: true
|
|
30
|
+
|
|
31
|
+
jobs:
|
|
32
|
+
lint:
|
|
33
|
+
name: Lint & Format Check
|
|
34
|
+
runs-on: ubuntu-24.04
|
|
35
|
+
timeout-minutes: 15
|
|
36
|
+
permissions:
|
|
37
|
+
contents: read
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@9f698171ed81b15d1823a05fc7211befd50c8ae0 # v6.0.3
|
|
40
|
+
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
41
|
+
with:
|
|
42
|
+
enable-cache: true
|
|
43
|
+
- run: uv sync --frozen --extra dev
|
|
44
|
+
- run: uv run --frozen ruff check .
|
|
45
|
+
- run: uv run --frozen ruff format --check .
|
|
46
|
+
|
|
47
|
+
type-check:
|
|
48
|
+
name: Type Check & Import Contracts
|
|
49
|
+
runs-on: ubuntu-24.04
|
|
50
|
+
timeout-minutes: 15
|
|
51
|
+
permissions:
|
|
52
|
+
contents: read
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@9f698171ed81b15d1823a05fc7211befd50c8ae0 # v6.0.3
|
|
55
|
+
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
56
|
+
with:
|
|
57
|
+
enable-cache: true
|
|
58
|
+
- run: uv sync --frozen --extra dev
|
|
59
|
+
- run: uv run --frozen ty check src/ezcompiler/
|
|
60
|
+
- run: uv run --frozen pyright
|
|
61
|
+
- run: PYTHONPATH=src uv run --frozen lint-imports
|
|
62
|
+
|
|
63
|
+
test:
|
|
64
|
+
name: Tests (Python ${{ matrix.python }})
|
|
65
|
+
needs: [lint, type-check]
|
|
66
|
+
runs-on: ubuntu-24.04
|
|
67
|
+
timeout-minutes: 25
|
|
68
|
+
permissions:
|
|
69
|
+
contents: read
|
|
70
|
+
strategy:
|
|
71
|
+
fail-fast: false
|
|
72
|
+
matrix:
|
|
73
|
+
python: ["3.13"]
|
|
74
|
+
steps:
|
|
75
|
+
- uses: actions/checkout@9f698171ed81b15d1823a05fc7211befd50c8ae0 # v6.0.3
|
|
76
|
+
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
77
|
+
with:
|
|
78
|
+
python-version: ${{ matrix.python }}
|
|
79
|
+
enable-cache: true
|
|
80
|
+
- run: uv sync --frozen --extra dev
|
|
81
|
+
- run: uv run --frozen pytest
|
|
82
|
+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
83
|
+
if: matrix.python == '3.13' && always()
|
|
84
|
+
with:
|
|
85
|
+
name: coverage-report
|
|
86
|
+
path: |
|
|
87
|
+
coverage.xml
|
|
88
|
+
htmlcov/
|
|
89
|
+
retention-days: 7
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Deploy Documentation Workflow
|
|
2
|
+
|
|
3
|
+
`docs.yml` builds and deploys the MkDocs Material documentation to GitHub Pages
|
|
4
|
+
(`https://neuraaak.github.io/ezplog/`). It is normally called by `auto-tag.yml`
|
|
5
|
+
after a tag is created or moved, but can also be run manually.
|
|
6
|
+
|
|
7
|
+
## Triggers
|
|
8
|
+
|
|
9
|
+
| Event | How |
|
|
10
|
+
| ------------------- | ---------------------------------------------------- |
|
|
11
|
+
| `workflow_call` | Called by `auto-tag.yml` with boolean input `deploy` |
|
|
12
|
+
| `workflow_dispatch` | Manual run from the Actions tab (always deploys) |
|
|
13
|
+
|
|
14
|
+
`workflow_call` input `deploy` (boolean, default `false`):
|
|
15
|
+
|
|
16
|
+
- `true` → full deploy to GitHub Pages (release mode)
|
|
17
|
+
- `false` → build + checks only, no push (preview mode)
|
|
18
|
+
|
|
19
|
+
## Job: `deploy`
|
|
20
|
+
|
|
21
|
+
Single job, runs on `ubuntu-24.04`. Steps in order:
|
|
22
|
+
|
|
23
|
+
| Step | Command / Action |
|
|
24
|
+
| ------------------ | ---------------------------------------------------------------------------------------------------------- |
|
|
25
|
+
| Checkout | Full history (`fetch-depth: 0`) required for git-cliff |
|
|
26
|
+
| Install | `uv sync --frozen` with `docs` and `test` extras |
|
|
27
|
+
| Tests | `uv run pytest --cov=src/ezplog --cov-report=html --cov-report=xml` — produces `htmlcov/` + `coverage.xml` |
|
|
28
|
+
| Import contracts | `PYTHONPATH=src uv run lint-imports` |
|
|
29
|
+
| Architecture graph | Runs `.scripts/dev/generate_architecture_graph.py` if present |
|
|
30
|
+
| Changelog | `git-cliff` writes `docs/changelog.md` from conventional commits |
|
|
31
|
+
| Resolve version | Reads `version` from `pyproject.toml`; fails if absent |
|
|
32
|
+
| Wait for PyPI | **Deploy mode only** — polls `pypi.org/pypi/ezplog/<version>/json` every 15 s, timeout 900 s |
|
|
33
|
+
| Git config | **Deploy mode only** — configures `github-actions[bot]` user for mike |
|
|
34
|
+
| Deploy | **Deploy mode only** — `mike deploy --push --update-aliases <version> latest` + `mike set-default latest` |
|
|
35
|
+
| Preview summary | **Preview mode only** — writes a step summary, no Pages push |
|
|
36
|
+
|
|
37
|
+
Deploy mode = `inputs.deploy == true` or `github.event_name == 'workflow_dispatch'`.
|
|
38
|
+
|
|
39
|
+
## Concurrency
|
|
40
|
+
|
|
41
|
+
Group `docs-$ref` with `cancel-in-progress: true` — a new docs run on the same ref
|
|
42
|
+
cancels the previous one.
|
|
43
|
+
|
|
44
|
+
## Permissions
|
|
45
|
+
|
|
46
|
+
`contents: write` is required so mike can push to the `gh-pages` branch.
|
|
47
|
+
|
|
48
|
+
## GitHub Pages setup
|
|
49
|
+
|
|
50
|
+
Pages must be configured to serve from the `gh-pages` branch:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
Repository → Settings → Pages → Source: Deploy from a branch → gh-pages / root
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`mike` manages versioned aliases (`latest`) and creates/updates this branch automatically.
|
|
57
|
+
|
|
58
|
+
## Local preview
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv sync --extra docs
|
|
62
|
+
uv run mkdocs serve
|
|
63
|
+
# Open http://127.0.0.1:8000
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Strict build (fails on warnings):
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
uv run mkdocs build --strict
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Manual trigger
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
gh workflow run docs.yml
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Troubleshooting
|
|
79
|
+
|
|
80
|
+
**Tests fail** — coverage generation fails if tests are broken. Fix the tests
|
|
81
|
+
and re-run. Do not add `|| true` to mask failures.
|
|
82
|
+
|
|
83
|
+
**mkdocstrings "Module not found"** — verify the module path in `docs/api/*.md`
|
|
84
|
+
matches the installed package. Run `uv run python -c "import ezplog"` to
|
|
85
|
+
confirm the package is importable.
|
|
86
|
+
|
|
87
|
+
**Permission denied on gh-pages** — check that `contents: write` is present and
|
|
88
|
+
that no branch-protection rule blocks force-pushes to `gh-pages`.
|
|
89
|
+
|
|
90
|
+
**Changelog not updating** — ensure `cliff.toml` exists at the repo root and
|
|
91
|
+
that commits follow the conventional commit format.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
name: Deploy Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
workflow_call:
|
|
6
|
+
inputs:
|
|
7
|
+
deploy:
|
|
8
|
+
description: "Deploy docs (true) or preview-only (false)"
|
|
9
|
+
type: boolean
|
|
10
|
+
default: false
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: write
|
|
14
|
+
|
|
15
|
+
concurrency:
|
|
16
|
+
group: docs-${{ github.ref }}
|
|
17
|
+
cancel-in-progress: true
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
deploy:
|
|
21
|
+
name: Build and Deploy Docs
|
|
22
|
+
runs-on: ubuntu-24.04
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@9f698171ed81b15d1823a05fc7211befd50c8ae0 # v6.0.3
|
|
26
|
+
with:
|
|
27
|
+
fetch-depth: 0
|
|
28
|
+
|
|
29
|
+
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
30
|
+
with:
|
|
31
|
+
enable-cache: true
|
|
32
|
+
|
|
33
|
+
- run: uv sync --frozen --extra docs --extra test
|
|
34
|
+
|
|
35
|
+
- name: Generate coverage report
|
|
36
|
+
run: uv run --frozen pytest --cov=src/ezcompiler --cov-report=html --cov-report=xml -q
|
|
37
|
+
|
|
38
|
+
- name: Enforce import contracts
|
|
39
|
+
run: PYTHONPATH=src uv run --frozen lint-imports
|
|
40
|
+
|
|
41
|
+
- name: Generate architecture graph
|
|
42
|
+
run: |
|
|
43
|
+
if [ -f ".scripts/dev/generate_architecture_graph.py" ]; then
|
|
44
|
+
uv run --frozen python .scripts/dev/generate_architecture_graph.py
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
- name: Generate changelog
|
|
48
|
+
uses: orhun/git-cliff-action@f50e11560dce63f7c33227798f90b924471a88b5 # v4
|
|
49
|
+
with:
|
|
50
|
+
config: cliff.toml
|
|
51
|
+
args: --output docs/changelog.md
|
|
52
|
+
|
|
53
|
+
- name: Resolve docs version
|
|
54
|
+
id: docs_version
|
|
55
|
+
run: |
|
|
56
|
+
VERSION=$(grep -E '^version\s*=\s*"' pyproject.toml | head -1 | sed 's/.*version\s*=\s*"\([^"]*\)".*/\1/')
|
|
57
|
+
if [ -z "$VERSION" ]; then
|
|
58
|
+
echo "::error::No version found in pyproject.toml"
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
62
|
+
echo "Version: $VERSION"
|
|
63
|
+
|
|
64
|
+
- name: Configure git for mike
|
|
65
|
+
if: inputs.deploy || github.event_name == 'workflow_dispatch'
|
|
66
|
+
run: |
|
|
67
|
+
git config user.name "github-actions[bot]"
|
|
68
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
69
|
+
|
|
70
|
+
- name: Deploy documentation with mike
|
|
71
|
+
if: inputs.deploy || github.event_name == 'workflow_dispatch'
|
|
72
|
+
env:
|
|
73
|
+
DOCS_VERSION: ${{ steps.docs_version.outputs.version }}
|
|
74
|
+
run: |
|
|
75
|
+
uv run --frozen mike deploy --push --update-aliases "$DOCS_VERSION" latest
|
|
76
|
+
uv run --frozen mike set-default --push latest
|
|
77
|
+
|
|
78
|
+
- name: Preview mode summary
|
|
79
|
+
if: github.event_name == 'workflow_call' && !inputs.deploy
|
|
80
|
+
run: |
|
|
81
|
+
echo "## 🔎 Docs Preview Mode" >> $GITHUB_STEP_SUMMARY
|
|
82
|
+
echo "- Event: ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
|
|
83
|
+
echo "- Build and checks completed." >> $GITHUB_STEP_SUMMARY
|
|
84
|
+
echo "- Documentation deploy step is intentionally skipped." >> $GITHUB_STEP_SUMMARY
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Publish to PyPI Workflow
|
|
2
|
+
|
|
3
|
+
`publish-pypi.yml` builds the package and publishes it to PyPI. It is normally
|
|
4
|
+
triggered by `auto-tag.yml` after a new version tag is created, but can also
|
|
5
|
+
be run manually.
|
|
6
|
+
|
|
7
|
+
## Triggers
|
|
8
|
+
|
|
9
|
+
| Event | How |
|
|
10
|
+
| ------------------- | ------------------------------------------------------ |
|
|
11
|
+
| `workflow_call` | Called by `auto-tag.yml` with `version` + `tag` inputs |
|
|
12
|
+
| `workflow_dispatch` | Manual run from the Actions tab |
|
|
13
|
+
|
|
14
|
+
Manual runs have a `skip_tests` option (default `false`, not recommended).
|
|
15
|
+
|
|
16
|
+
## Authentication
|
|
17
|
+
|
|
18
|
+
Publishing uses **OIDC trusted publishing** — no stored secret. The workflow
|
|
19
|
+
mints a short-lived token that PyPI trusts directly via the `id-token: write`
|
|
20
|
+
permission. The trusted publisher must be configured on pypi.org under the
|
|
21
|
+
ezplog project settings:
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
pypi.org → Manage project ezplog → Publishing → Add a new publisher
|
|
25
|
+
Owner: neuraaak
|
|
26
|
+
Repo: ezplog
|
|
27
|
+
Workflow: publish-pypi.yml
|
|
28
|
+
Environment: pypi
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Jobs
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
validate (build + test) ──► publish (OIDC deploy)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### `validate` — Validate & Build
|
|
38
|
+
|
|
39
|
+
1. Resolve version: uses `inputs.version` if provided (workflow_call), otherwise reads from `pyproject.toml`
|
|
40
|
+
2. Preview mode summary — printed if triggered by push/PR or preview tag (no failure, informational only)
|
|
41
|
+
3. `uv sync --frozen --extra dev`
|
|
42
|
+
4. `PYTHONPATH=src uv run lint-imports` — import contracts
|
|
43
|
+
5. `uv run pytest` — full suite (skipped if `skip_tests=true`)
|
|
44
|
+
6. `uv build` — produces `dist/*.whl` and `dist/*.tar.gz`
|
|
45
|
+
7. `uv run twine check dist/*` — validates package metadata
|
|
46
|
+
8. Wheel integrity check: `python -m zipfile -t dist/*.whl` + inline script verifying `ezplog/` is present in the wheel
|
|
47
|
+
9. Upload `dist/` as a job artifact (retained 1 day)
|
|
48
|
+
|
|
49
|
+
### `publish` — Publish to PyPI (OIDC)
|
|
50
|
+
|
|
51
|
+
Runs only if `validate` succeeds **and** the event is `workflow_dispatch` or a
|
|
52
|
+
`workflow_call` whose `tag` input does not start with `preview-`. Downloads the
|
|
53
|
+
artifact built upstream (no rebuild). Steps:
|
|
54
|
+
|
|
55
|
+
1. `actions/download-artifact` — retrieves `dist/`
|
|
56
|
+
2. `pypa/gh-action-pypi-publish@v1.14.0` — publishes via OIDC, no password
|
|
57
|
+
|
|
58
|
+
> **Note — attestations disabled:** when called as a reusable workflow from
|
|
59
|
+
> `auto-tag.yml`, the OIDC token's Build Config URI reflects the caller
|
|
60
|
+
> (`auto-tag.yml`) rather than `publish-pypi.yml`, causing PyPI Trusted
|
|
61
|
+
> Publisher verification to fail. `attestations: false` works around this.
|
|
62
|
+
|
|
63
|
+
The job runs in the `pypi` environment. Configure required reviewers there
|
|
64
|
+
in Repository → Settings → Environments if you want a manual gate.
|
|
65
|
+
|
|
66
|
+
## Concurrency
|
|
67
|
+
|
|
68
|
+
A `publish` concurrency group with `cancel-in-progress: false` prevents two
|
|
69
|
+
simultaneous publish runs. A run in progress is never interrupted.
|
|
70
|
+
|
|
71
|
+
## Release workflow
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
1. Bump version in pyproject.toml
|
|
75
|
+
2. Commit & push to main
|
|
76
|
+
→ auto-tag.yml detects a new version, creates vX.Y.Z tag
|
|
77
|
+
→ triggers publish-pypi.yml automatically
|
|
78
|
+
3. Verify on https://pypi.org/project/ezplog/
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Manual trigger via gh CLI:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
gh workflow run publish-pypi.yml
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Troubleshooting
|
|
88
|
+
|
|
89
|
+
**Version mismatch** — the `version` input from auto-tag differs from
|
|
90
|
+
`pyproject.toml`. Bump the version, commit, and push again.
|
|
91
|
+
|
|
92
|
+
**OIDC failure** — check that the trusted publisher on pypi.org matches
|
|
93
|
+
the repo name, workflow filename (`publish-pypi.yml`), and environment name
|
|
94
|
+
(`pypi`) exactly.
|
|
95
|
+
|
|
96
|
+
**Tests fail** — run `uv run pytest` locally, fix, push. Do not use
|
|
97
|
+
`skip_tests=true` to work around failures.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
workflow_call:
|
|
6
|
+
inputs:
|
|
7
|
+
version:
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
10
|
+
tag:
|
|
11
|
+
required: true
|
|
12
|
+
type: string
|
|
13
|
+
|
|
14
|
+
permissions: {}
|
|
15
|
+
|
|
16
|
+
concurrency:
|
|
17
|
+
group: publish-${{ github.ref }}
|
|
18
|
+
cancel-in-progress: false
|
|
19
|
+
|
|
20
|
+
env:
|
|
21
|
+
PACKAGE_NAME: ezcompiler
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
validate:
|
|
25
|
+
name: Validate & Build
|
|
26
|
+
runs-on: ubuntu-24.04
|
|
27
|
+
permissions:
|
|
28
|
+
contents: read
|
|
29
|
+
outputs:
|
|
30
|
+
version: ${{ steps.version.outputs.version }}
|
|
31
|
+
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@9f698171ed81b15d1823a05fc7211befd50c8ae0 # v6.0.3
|
|
34
|
+
|
|
35
|
+
- name: Resolve version
|
|
36
|
+
id: version
|
|
37
|
+
env:
|
|
38
|
+
INPUT_VERSION: ${{ inputs.version || '' }}
|
|
39
|
+
run: |
|
|
40
|
+
VERSION="$INPUT_VERSION"
|
|
41
|
+
if [ -z "$VERSION" ]; then
|
|
42
|
+
VERSION=$(grep -E '^version\s*=\s*"' pyproject.toml | head -1 | sed 's/.*version\s*=\s*"\([^"]*\)".*/\1/')
|
|
43
|
+
fi
|
|
44
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
45
|
+
echo "Version: $VERSION"
|
|
46
|
+
|
|
47
|
+
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
48
|
+
with:
|
|
49
|
+
enable-cache: true
|
|
50
|
+
|
|
51
|
+
- run: uv sync --frozen --extra dev
|
|
52
|
+
|
|
53
|
+
- name: Enforce import contracts
|
|
54
|
+
run: PYTHONPATH=src uv run --frozen lint-imports
|
|
55
|
+
|
|
56
|
+
- name: Build package
|
|
57
|
+
run: uv build
|
|
58
|
+
|
|
59
|
+
- name: Check package
|
|
60
|
+
run: uv run --frozen twine check dist/*
|
|
61
|
+
|
|
62
|
+
- name: Verify wheel installation
|
|
63
|
+
run: |
|
|
64
|
+
python -m zipfile -t dist/*.whl
|
|
65
|
+
python - <<'PY'
|
|
66
|
+
import glob
|
|
67
|
+
import sys
|
|
68
|
+
import zipfile
|
|
69
|
+
|
|
70
|
+
wheels = glob.glob("dist/*.whl")
|
|
71
|
+
if not wheels:
|
|
72
|
+
raise SystemExit("No wheel found in dist/")
|
|
73
|
+
|
|
74
|
+
with zipfile.ZipFile(wheels[0]) as zf:
|
|
75
|
+
names = zf.namelist()
|
|
76
|
+
|
|
77
|
+
if not any(name.startswith("ezcompiler/") for name in names):
|
|
78
|
+
raise SystemExit("Wheel does not contain ezcompiler package")
|
|
79
|
+
|
|
80
|
+
print("Wheel integrity check passed")
|
|
81
|
+
PY
|
|
82
|
+
|
|
83
|
+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
84
|
+
with:
|
|
85
|
+
name: dist
|
|
86
|
+
path: dist/
|
|
87
|
+
retention-days: 1
|
|
88
|
+
|
|
89
|
+
publish:
|
|
90
|
+
name: Publish to PyPI (OIDC)
|
|
91
|
+
needs: validate
|
|
92
|
+
if: github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call'
|
|
93
|
+
runs-on: ubuntu-24.04
|
|
94
|
+
permissions:
|
|
95
|
+
contents: read
|
|
96
|
+
id-token: write
|
|
97
|
+
environment:
|
|
98
|
+
name: pypi
|
|
99
|
+
url: https://pypi.org/project/${{ env.PACKAGE_NAME }}/${{ needs.validate.outputs.version }}/
|
|
100
|
+
|
|
101
|
+
steps:
|
|
102
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
103
|
+
with:
|
|
104
|
+
name: dist
|
|
105
|
+
path: dist/
|
|
106
|
+
|
|
107
|
+
- uses: pypa/gh-action-pypi-publish@v1.14.0
|
|
108
|
+
with:
|
|
109
|
+
verbose: true
|
|
110
|
+
# Attestations disabled: when called as a reusable workflow from
|
|
111
|
+
# auto-tag.yml, the OIDC token's Build Config URI reflects the
|
|
112
|
+
# caller (auto-tag.yml) rather than this workflow, causing PyPI
|
|
113
|
+
# Trusted Publisher verification to fail.
|
|
114
|
+
attestations: false
|
|
115
|
+
|
|
116
|
+
- name: Summary
|
|
117
|
+
run: |
|
|
118
|
+
echo "## 📦 Published to PyPI" >> $GITHUB_STEP_SUMMARY
|
|
119
|
+
echo "- **Package**: ${{ env.PACKAGE_NAME }}" >> $GITHUB_STEP_SUMMARY
|
|
120
|
+
echo "- **Version**: ${{ needs.validate.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
|
121
|
+
echo "- **URL**: https://pypi.org/project/${{ env.PACKAGE_NAME }}/${{ needs.validate.outputs.version }}/" >> $GITHUB_STEP_SUMMARY
|