-
Notifications
You must be signed in to change notification settings - Fork 0
168 lines (134 loc) · 5.66 KB
/
Copy pathpre-release.yml
File metadata and controls
168 lines (134 loc) · 5.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# ============================================================
# .github/workflows/pre-release.yml (pypi pre-release checks)
# ============================================================
# Updated: 2026-06-01
# WHY-FILE: Pre-release gate. Validates the repo and builds the distribution
# once, then uploads it as the `dist` artifact so the release
# workflow publishes the exact bytes that were checked here.
#
# OBS: This workflow does not trigger on tags directly. It runs via
# workflow_call from release-pypi.yml (which is tag-triggered) and via
# manual workflow_dispatch. The tag-version assertion self-skips when
# not running on a tag, so manual dispatch is safe.
#
# OWNS:
# schema validation
# SE_MANIFEST.toml validation
# artifact integrity checks
# build-once: produces the `dist` artifact consumed by the release workflow
name: Pre-Release Checks and Build
on:
workflow_call: # WHY: Called by release-pypi.yml on version tags.
workflow_dispatch: # WHY: Manual trigger for ad hoc pre-release checks.
permissions: # WHY: Least privilege. This workflow only reads and checks.
contents: read
env:
PYTHONUNBUFFERED: "1" # WHY: Real-time logging.
PYTHONIOENCODING: "utf-8" # WHY: Ensure UTF-8 encoding for international characters.
jobs:
pre-release:
runs-on: ubuntu-latest
timeout-minutes: 30 # WHY: Prevent hanging jobs. If over, it is likely stuck.
env:
PYTHON_VERSION: "3.15"
steps:
# === ASSEMBLE ===
- name: A1) Checkout repository with full history and tags
uses: actions/checkout@v7
with:
fetch-depth: 0 # WHY: hatch-vcs needs full history to derive version from tags.
fetch-tags: true
ref: ${{ github.ref }}
- name: A2) Install uv (with caching and uv.lock awareness)
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
- name: A3) Install Python ${{ env.PYTHON_VERSION }}
run: uv python install ${{ env.PYTHON_VERSION }}
- name: A4) Display versions
run: |
uv --version
uv run python --version
# === BASELINE BUILD (while git is pristine) ===
- name: B1) Extract plain version from tag (no leading 'v')
id: ver
shell: bash
run: |
if [[ "${GITHUB_REF_TYPE}" != "tag" ]]; then
echo "plain=" >> "$GITHUB_OUTPUT"
echo "Not running on a tag; skipping tag-version assertion."
exit 0
fi
echo "plain=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
- name: B2) Verify git is clean before build
run: |
echo "Git status:"
git status --short
echo "Git describe:"
git describe --tags --always --dirty
if [[ $(git status --porcelain) ]]; then
echo "ERROR: Git tree is dirty before build!"
exit 1
fi
- name: B3) Build sdist + wheel
# WHY: hatch-vcs derives version from the git tag; build before uv sync
# so working-tree changes cannot invalidate the clean check above.
run: uv build
- name: B4) Ensure built artifact version matches tag
if: github.ref_type == 'tag'
shell: bash
run: |
set -e
TAG="${{ steps.ver.outputs.plain }}"
echo "Tag version: $TAG"
ls dist
if ! ls dist/*"$TAG"*.whl dist/*"$TAG"*.tar.gz >/dev/null 2>&1; then
echo "ERROR: Built artifact version does not match tag $TAG"
exit 1
fi
echo "Artifact version matches tag."
- name: B5) Verify built distribution artifacts
run: uvx twine check dist/*
- name: B6) Sync dependencies after build
run: uv sync --extra dev --extra docs --upgrade
# === CHECKS ===
- name: C1) Pyright
run: uv run pyright
- name: C2) Tests
run: uv run pytest
- name: C3) Ruff format check
run: uv run ruff format --check .
- name: C4) Ruff lint
run: uv run ruff check .
- name: C5) Build docs (gate)
# WHY: Fail here if docs are broken, before the irreversible PyPI publish.
# OBS: This is a validation build only; the release workflow rebuilds and
# deploys docs in its own job. zensical.toml is required at release.
run: |
if [ ! -f "zensical.toml" ]; then
echo "ERROR: zensical.toml not found; docs are required for release." >> "$GITHUB_STEP_SUMMARY"
exit 1
fi
uv run zensical build
# === LOCAL CLI / MANIFEST CHECKS ===
- name: E0) Validate SE_MANIFEST.toml against schema
run: uvx se-manifest-schema validate-manifest --path SE_MANIFEST.toml --strict
- name: E1) se-theory-reference --help
run: uv run se-theory-reference --help
- name: E2) se-theory-reference validate --help
run: uv run se-theory-reference validate --help
- name: E3) se-theory-reference scaffold --help
run: uv run se-theory-reference scaffold --help
- name: E4) se-theory-reference catalog --help
run: uv run se-theory-reference catalog --help
- name: E5) se-theory-reference inspect --help
run: uv run se-theory-reference inspect --help
# === PUBLISH THE BUILT ARTIFACT FOR DOWNSTREAM JOBS ===
- name: Z1) Upload built distribution as artifact
uses: actions/upload-artifact@v7
with:
name: dist
path: dist/
if-no-files-found: error # WHY: A release with no artifact is a failure.
retention-days: 1 # WHY: Only needed to hand off to the release run.