Skip to content

Commit 28534bd

Browse files
committed
ci(release): add trusted publishing workflow and harden benchmark isolation
1 parent d7f8447 commit 28534bd

6 files changed

Lines changed: 124 additions & 4 deletions

File tree

.github/workflows/benchmark.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ jobs:
9898

9999
- name: Install dependencies (macOS local benchmark)
100100
if: env.BENCH_ENABLED == '1' && runner.os == 'macOS'
101-
run: uv sync --all-extras --dev
101+
run: uv sync --extra dev
102102

103103
- name: Set benchmark output path
104104
if: env.BENCH_ENABLED == '1'

.github/workflows/publish.yml

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
name: publish
2+
run-name: >-
3+
publish • ${{ github.event_name }} •
4+
${{ github.event.release.tag_name || inputs.repository || github.ref_name }}
5+
6+
on:
7+
release:
8+
types: [published]
9+
workflow_dispatch:
10+
inputs:
11+
repository:
12+
description: Target package index
13+
required: true
14+
default: testpypi
15+
type: choice
16+
options:
17+
- testpypi
18+
- pypi
19+
20+
permissions:
21+
contents: read
22+
23+
concurrency:
24+
group: publish-${{ github.event.release.tag_name || github.ref }}
25+
cancel-in-progress: false
26+
27+
jobs:
28+
build:
29+
runs-on: ubuntu-latest
30+
steps:
31+
- name: Checkout
32+
uses: actions/checkout@v6.0.2
33+
34+
- name: Set up Python
35+
uses: actions/setup-python@v6.2.0
36+
with:
37+
python-version: "3.13"
38+
allow-prereleases: true
39+
40+
- name: Set up uv
41+
uses: astral-sh/setup-uv@v5
42+
with:
43+
enable-cache: true
44+
45+
- name: Verify release tag matches project version
46+
if: ${{ github.event_name == 'release' }}
47+
shell: bash
48+
run: |
49+
set -euo pipefail
50+
project_version="$(python - <<'PY'
51+
import pathlib, tomllib
52+
payload = tomllib.loads(pathlib.Path("pyproject.toml").read_text(encoding="utf-8"))
53+
print(payload["project"]["version"])
54+
PY
55+
)"
56+
release_tag="${{ github.event.release.tag_name }}"
57+
normalized_tag="${release_tag#v}"
58+
if [ "$normalized_tag" != "$project_version" ]; then
59+
echo "release tag $release_tag does not match project version $project_version" >&2
60+
exit 1
61+
fi
62+
63+
- name: Build distributions
64+
run: uv run --with build python -m build --sdist --wheel
65+
66+
- name: Validate distributions
67+
run: uv run --with twine twine check dist/*
68+
69+
- name: Upload distributions
70+
uses: actions/upload-artifact@v4
71+
with:
72+
name: python-package-distributions
73+
path: dist/
74+
if-no-files-found: error
75+
76+
publish-testpypi:
77+
if: ${{ github.event_name == 'workflow_dispatch' && inputs.repository == 'testpypi' }}
78+
needs: build
79+
runs-on: ubuntu-latest
80+
environment: testpypi
81+
permissions:
82+
contents: read
83+
id-token: write
84+
steps:
85+
- name: Download distributions
86+
uses: actions/download-artifact@v5
87+
with:
88+
name: python-package-distributions
89+
path: dist/
90+
91+
- name: Publish to TestPyPI
92+
uses: pypa/gh-action-pypi-publish@release/v1
93+
with:
94+
repository-url: https://test.pypi.org/legacy/
95+
96+
publish-pypi:
97+
if: >-
98+
${{
99+
github.event_name == 'release' ||
100+
(github.event_name == 'workflow_dispatch' && inputs.repository == 'pypi')
101+
}}
102+
needs: build
103+
runs-on: ubuntu-latest
104+
environment: pypi
105+
permissions:
106+
contents: read
107+
id-token: write
108+
steps:
109+
- name: Download distributions
110+
uses: actions/download-artifact@v5
111+
with:
112+
name: python-package-distributions
113+
path: dist/
114+
115+
- name: Publish to PyPI
116+
uses: pypa/gh-action-pypi-publish@release/v1

.github/workflows/tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
enable-cache: true
3636

3737
- name: Install dependencies
38-
run: uv sync --all-extras --dev
38+
run: uv sync --extra dev --extra mcp
3939

4040
- name: Run tests
4141
# Smoke CLI tests intentionally disable subprocess coverage collection
@@ -67,7 +67,7 @@ jobs:
6767
enable-cache: true
6868

6969
- name: Install dependencies
70-
run: uv sync --all-extras --dev
70+
run: uv sync --extra dev --extra mcp
7171

7272
- name: Ruff
7373
run: uv run ruff check .

benchmarks/run_benchmark.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
"-1",
5151
"--min-docstring-coverage",
5252
"-1",
53+
"--no-api-surface",
54+
"--no-update-metrics-baseline",
5355
)
5456

5557

benchmarks/run_docker_benchmark.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
set -euo pipefail
33

44
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5-
IMAGE_TAG="${IMAGE_TAG:-codeclone-benchmark:2.0.0b5}"
5+
IMAGE_TAG="${IMAGE_TAG:-codeclone-benchmark:local}"
66
OUT_DIR="${OUT_DIR:-$ROOT_DIR/.cache/benchmarks}"
77
OUTPUT_BASENAME="${OUTPUT_BASENAME:-codeclone-benchmark.json}"
88
CPUSET="${CPUSET:-0}"

tests/test_benchmark.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ def test_benchmark_neutral_args_disable_repo_quality_gates() -> None:
7676
assert "--no-fail-on-new-metrics" in BENCHMARK_NEUTRAL_ARGS
7777
assert "--no-fail-cycles" in BENCHMARK_NEUTRAL_ARGS
7878
assert "--no-fail-dead-code" in BENCHMARK_NEUTRAL_ARGS
79+
assert "--no-api-surface" in BENCHMARK_NEUTRAL_ARGS
80+
assert "--no-update-metrics-baseline" in BENCHMARK_NEUTRAL_ARGS
7981
assert "--fail-health" in BENCHMARK_NEUTRAL_ARGS
8082
assert "--min-typing-coverage" in BENCHMARK_NEUTRAL_ARGS
8183
assert "--min-docstring-coverage" in BENCHMARK_NEUTRAL_ARGS

0 commit comments

Comments
 (0)