Skip to content

Commit 2786dea

Browse files
committed
fix(release): fixed an issue where a dirty version from the release process prevented release
Signed-off-by: Adam Poulemanos <adam@knit.li>
1 parent fcdb991 commit 2786dea

5 files changed

Lines changed: 151 additions & 47 deletions

File tree

.github/workflows/_reusable-build.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ on:
2727
required: false
2828
type: boolean
2929
default: false
30+
ref:
31+
description: Git ref to checkout (tag, branch, or SHA). Defaults to the triggering ref.
32+
required: false
33+
type: string
34+
default: ""
3035
jobs:
3136
build:
3237
name: Build Package
@@ -40,6 +45,7 @@ jobs:
4045
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
4146
with:
4247
fetch-depth: 0
48+
ref: ${{ inputs.ref || github.ref }}
4349
- name: Install build dependencies
4450
run: |
4551
sudo apt-get update

.github/workflows/release.yml

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ jobs:
5151
python-version: "3.12"
5252
upload-artifacts: true
5353
clean-build: true
54+
# Pin checkout to the tag so uv-dynamic-versioning derives a clean
55+
# version (e.g. 0.1.2) instead of a post-release dev suffix.
56+
# For workflow_dispatch the user supplies the tag; for tag pushes
57+
# github.ref is already refs/tags/vX.Y.Z.
58+
ref: ${{ github.event_name == 'workflow_dispatch' && format('refs/tags/{0}', github.event.inputs.tag) || github.ref }}
5459
secrets: inherit
5560
github-release:
5661
name: Create GitHub Release
@@ -95,16 +100,29 @@ jobs:
95100
# section above existing content. The curated v0.1.0 history (and any
96101
# later manual edits) below the BEGIN-CURATED-HISTORY marker is preserved.
97102
# Skipped on prereleases to keep CHANGELOG.md focused on stable releases.
103+
#
104+
# Uses an explicit commit range (like the release notes step) because
105+
# `-u` alone finds no unreleased commits when the tag already exists.
98106
if: ${{ !(contains(steps.version.outputs.version, 'a') || contains(steps.version.outputs.version, 'b') || contains(steps.version.outputs.version, 'rc')) }}
99107
run: |
100-
git-cliff -u --tag "${{ steps.version.outputs.tag }}" --prepend CHANGELOG.md
108+
CURRENT_TAG="${{ steps.version.outputs.tag }}"
109+
PREVIOUS_TAG="$(git tag --sort=-version:refname \
110+
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+([ab]|rc|-alpha|-beta)?[0-9]*(\.[0-9]+)?$' \
111+
| head -2 | tail -1 || echo "")"
112+
113+
if [ -n "$PREVIOUS_TAG" ] && [ "$PREVIOUS_TAG" != "$CURRENT_TAG" ]; then
114+
git-cliff -u --tag "$CURRENT_TAG" "$PREVIOUS_TAG..$CURRENT_TAG" --prepend CHANGELOG.md
115+
else
116+
git-cliff -u --tag "$CURRENT_TAG" --prepend CHANGELOG.md
117+
fi
118+
101119
if git diff --quiet -- CHANGELOG.md; then
102120
echo "CHANGELOG.md already up to date"
103121
else
104122
git config user.name "github-actions[bot]"
105123
git config user.email "github-actions[bot]@users.noreply.github.com"
106124
git add CHANGELOG.md
107-
git commit -m "docs(changelog): prepend ${{ steps.version.outputs.tag }} [skip ci]"
125+
git commit -m "docs(changelog): prepend $CURRENT_TAG [skip ci]"
108126
# Push to default branch; tag pushes are detached so target main explicitly
109127
git push origin HEAD:main
110128
fi

CHANGELOG.md

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,60 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## [0.1.2] - 2026-04-16
9-
<!--
10-
SPDX-FileCopyrightText: 2026 Knitli Inc.
119

12-
SPDX-License-Identifier: MIT OR Apache-2.0
13-
-->
10+
### Bug Fixes
11+
12+
- fix: prevent Python 3.12 CI hang by excluding real_providers tests and hardening timeouts ([#337](https://github.com/knitli/codeweaver/pull/337))
13+
- fix: use time.monotonic() in ResourceGovernor to prevent Python 3.12 CI hang ([#336](https://github.com/knitli/codeweaver/pull/336))
14+
- fix(ci): remove redundant post-pytest coverage commands causing all CI runs to fail ([#334](https://github.com/knitli/codeweaver/pull/334))
15+
- fix(tests): address nightly test failures ([#332](https://github.com/knitli/codeweaver/pull/332))
16+
- fix: test-cov mise task silently drops CLI args; profile test wrong on 3.14 ([#331](https://github.com/knitli/codeweaver/pull/331))
17+
- fix: restore PR #302 fixes reverted by PR #319's stale main merge ([#326](https://github.com/knitli/codeweaver/pull/326))
18+
- fix: configure workspace members for uv-dynamic-versioning and update Dockerfile to use uv build ([#325](https://github.com/knitli/codeweaver/pull/325))
19+
- fix: ensure non-destructive changelog generation
20+
- fix(ci): prevent Claude workflow from triggering on bot reviews; add agent identification ([#323](https://github.com/knitli/codeweaver/pull/323))
21+
- fix(tests): add per-Python-version thresholds for chunker benchmarks ([#317](https://github.com/knitli/codeweaver/pull/317))
22+
- fix(providers): resolve Exa service card lateimport name mismatch ([#316](https://github.com/knitli/codeweaver/pull/316))
23+
- fix(di): restore lenient sync settings init and fix mise task hygiene ([#314](https://github.com/knitli/codeweaver/pull/314))
24+
- fix(tests): reorder decorators to ensure skip_ci marker applies to parametrized tests ([#315](https://github.com/knitli/codeweaver/pull/315))
25+
- fix: add coverage combine step for parallel coverage reporting ([#309](https://github.com/knitli/codeweaver/pull/309))
26+
- fix(providers): guard EmbedByTypeResponse import with TYPE_CHECKING ([#305](https://github.com/knitli/codeweaver/pull/305))
27+
- fix: handle UNSET sentinel correctly in ProviderSettings initialization ([#301](https://github.com/knitli/codeweaver/pull/301))
28+
29+
### CI/CD
30+
31+
- ci(smoke): add install-profile smoke matrix + nightly/weekly integration ([#320](https://github.com/knitli/codeweaver/pull/320))
32+
33+
### Documentation
34+
35+
- docs: launch CodeWeaver docs site with mirrored API reference ([#330](https://github.com/knitli/codeweaver/pull/330))
36+
37+
### Features
38+
39+
- feat: integrate hatch-fancy-pypi-readme for better pypi readme resolution (fix broken links)
40+
41+
### Maintenance
42+
43+
- chore(claude-plugin): Removed the CodeWeaver Claude Code plugin from the repo. The plugin is now part of the [Knitli Agent Toolshed](https://github.com/knitli/toolshed). You can add it with `/plugin marketplace add knitli/toolshed` and then `/plugin install codeweaver`
44+
- chore: re-establish REUSE compliance
45+
46+
### Performance
47+
48+
- Improve delimiter chunking performance and governor checks for Python 3.13 CI ([#335](https://github.com/knitli/codeweaver/pull/335))
49+
- Optimize text parsing using walrus operator ([#333](https://github.com/knitli/codeweaver/pull/333))
50+
- Optimize task generation ([#327](https://github.com/knitli/codeweaver/pull/327))
51+
- Optimize extension matching in language_from_path ([#318](https://github.com/knitli/codeweaver/pull/318))
52+
- Remove redundant lru_cache from _get_lang_patterns ([#324](https://github.com/knitli/codeweaver/pull/324))
53+
54+
### Testing
55+
56+
- Fix OSError caplog test: deterministic capture, precise assertions, REUSE compliance ([#319](https://github.com/knitli/codeweaver/pull/319))
57+
- Add testing for core language detection and configurations ([#322](https://github.com/knitli/codeweaver/pull/322))
58+
- test: cover UnicodeEncodeError in DelimiterChunker ([#321](https://github.com/knitli/codeweaver/pull/321))
59+
60+
### Refactoring
61+
62+
- refactor(deps): single-source dep management via uv-dynamic-versioning hook + install-smoke foundation ([#302](https://github.com/knitli/codeweaver/pull/302))
1463

1564
<!-- BEGIN-CURATED-HISTORY -->
1665

REUSE.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,17 @@ precedence = "override"
337337
SPDX-FileCopyrightText = "2025 GitHub Inc."
338338
SPDX-License-Identifier = "MIT"
339339

340+
# =============================================================================
341+
# CHANGELOG.md - Generated by git-cliff, cannot contain inline SPDX comments
342+
# =============================================================================
343+
# git-cliff's --prepend regenerates the header from the template, which
344+
# displaces any inline SPDX comments. Covered here instead.
345+
[[annotations]]
346+
path = "CHANGELOG.md"
347+
precedence = "override"
348+
SPDX-FileCopyrightText = "2026 Knitli Inc."
349+
SPDX-License-Identifier = "MIT OR Apache-2.0"
350+
340351
[[annotations]]
341352
path = ["docs-site/src/**", "docs-site/public/**"]
342353
precedence = "override"

cliff.toml

Lines changed: 61 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -24,47 +24,47 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2424
# - date: Commit date
2525
# - commits: List of commits for this version
2626
body = """
27-
{% if version -%}
28-
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
29-
{% else -%}
30-
## [Unreleased]
31-
{% endif -%}
27+
{%- if version %}
28+
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
29+
{%- else %}
30+
## [Unreleased]
31+
{%- endif %}
3232
{% for group, commits in commits | group_by(attribute="group") %}
33-
### {{ group | striptags | trim | upper_first }}
34-
{%- for commit in commits -%}
35-
{%- if commit.message is starting_with("SQUASH | ") -%}
36-
{# Handle squash merge format: "SQUASH | description | #123" #}
37-
{%- set_global parts = commit.message | split(pat=" | ") -%}
38-
{%- set_global pr_desc = parts | nth(n=1) | trim -%}
39-
{%- set_global pr_num = parts | nth(n=2) | replace(from="#", to="") | trim -%}
40-
{%- if pr_num is matching("^[0-9]+$") -%}
41-
- {{ pr_desc }} ([#{{ pr_num }}](https://github.com/knitli/codeweaver/pull/{{ pr_num }}))
42-
{%- else -%}
43-
- {{ pr_desc }}
44-
{%- endif -%}
45-
{%- elif commit.message is starting_with("Merge pull request") -%}
46-
{# Handle regular merge format: "Merge pull request #123 from org/branch | Description" #}
47-
{%- set_global pr_num = commit.message | replace(from="Merge pull request #", to="") | split(pat=" ") | first | trim -%}
48-
{%- if commit.message is containing(" | ") -%}
49-
{%- set_global parts = commit.message | split(pat=" | ") -%}
50-
{%- if parts | length >= 2 -%}
51-
{%- set_global pr_desc = parts | slice(start=1) | join(sep=" | ") | trim -%}
52-
{%- else -%}
53-
{%- set_global pr_desc = "No description" -%}
54-
{%- endif -%}
55-
{%- endif %}
56-
{%- if pr_num is matching("^[0-9]+$") -%}
57-
- {{ pr_desc }} ([#{{ pr_num }}](https://github.com/knitli/codeweaver/pull/{{ pr_num }}))
58-
{%- else -%}
59-
- {{ pr_desc }}
60-
{%- endif -%}
61-
{%- else %}
62-
- {{ commit.message | upper_first }}
63-
{%- endif -%}
64-
{%- if commit.breaking %}
65-
- **BREAKING**: {{ commit.breaking_description }}
66-
{%- endif -%}
67-
{% endfor %}
33+
### {{ group | striptags | trim | upper_first }}
34+
{% for commit in commits -%}
35+
{%- if commit.message is starting_with("SQUASH | ") -%}
36+
{# Handle squash merge format: "SQUASH | description | #123" #}
37+
{%- set_global parts = commit.message | split(pat=" | ") -%}
38+
{%- set_global pr_desc = parts | nth(n=1) | trim -%}
39+
{%- set_global pr_num = parts | nth(n=2) | replace(from="#", to="") | trim -%}
40+
{%- if pr_num is matching("^[0-9]+$") %}
41+
- {{ pr_desc }} ([#{{ pr_num }}](https://github.com/knitli/codeweaver/pull/{{ pr_num }}))
42+
{%- else %}
43+
- {{ pr_desc }}
44+
{%- endif -%}
45+
{%- elif commit.message is starting_with("Merge pull request") -%}
46+
{# Handle regular merge format: "Merge pull request #123 from org/branch | Description" #}
47+
{%- set_global pr_num = commit.message | replace(from="Merge pull request #", to="") | split(pat=" ") | first | trim -%}
48+
{%- if commit.message is containing(" | ") -%}
49+
{%- set_global parts = commit.message | split(pat=" | ") -%}
50+
{%- if parts | length >= 2 -%}
51+
{%- set_global pr_desc = parts | slice(start=1) | join(sep=" | ") | trim -%}
52+
{%- else -%}
53+
{%- set_global pr_desc = "No description" -%}
54+
{%- endif -%}
55+
{%- endif -%}
56+
{%- if pr_num is matching("^[0-9]+$") %}
57+
- {{ pr_desc }} ([#{{ pr_num }}](https://github.com/knitli/codeweaver/pull/{{ pr_num }}))
58+
{%- else %}
59+
- {{ pr_desc }}
60+
{%- endif -%}
61+
{%- else %}
62+
- {{ commit.message | upper_first }}
63+
{%- endif -%}
64+
{%- if commit.breaking %}
65+
- **BREAKING**: {{ commit.breaking_description }}
66+
{%- endif %}
67+
{%- endfor %}
6868
{% endfor %}
6969
"""
7070
# Template for the changelog footer
@@ -88,9 +88,17 @@ filter_unconventional = false
8888
split_commits = false
8989
# Preprocessors for both merge commits and squash merges
9090
commit_preprocessors = [
91+
# 0. Strip multi-line commit bodies — keep only the subject line.
92+
# git-cliff applies preprocessors to the full message, and regexes below
93+
# use `$` which in Rust regex means end-of-string by default. Stripping
94+
# the body first ensures `$` matches the end of the subject line.
95+
{ pattern = '\n[\s\S]*', replace = "" },
9196
# 1. Extract PR description from merge commits and append to subject
92-
# Input: "Merge pull request #123 from org/branch\n\nPR Description"
97+
# Input: "Merge pull request #123 from org/branch"
9398
# Output: "Merge pull request #123 from org/branch | PR Description"
99+
# (body already stripped, so this only fires for single-line merge commits
100+
# that had the description appended by a previous preprocessor run —
101+
# kept for backwards compatibility)
94102
{ pattern = 'Merge pull request (#[0-9]+) from ([^\n]+)\n+([\s\S]+)', replace = "Merge pull request ${1} from ${2} | ${3}" },
95103
# 2. Mark squash merge commits for easier template detection
96104
# Input: "feat: some feature (#123)"
@@ -119,6 +127,18 @@ commit_parsers = [
119127
{ message = "^SQUASH \\| chore", group = "Maintenance" },
120128
{ message = "^SQUASH \\| revert", group = "Reverts" },
121129
{ message = "^SQUASH \\|", group = "Other Changes" },
130+
# === Direct Conventional Commits (no PR number) ===
131+
# Fallback for commits pushed directly to main without a PR
132+
{ message = "^feat", group = "Features" },
133+
{ message = "^fix", group = "Bug Fixes" },
134+
{ message = "^docs", group = "Documentation" },
135+
{ message = "^perf", group = "Performance" },
136+
{ message = "^refactor", group = "Refactoring" },
137+
{ message = "^test", group = "Testing" },
138+
{ message = "^build", group = "Build System" },
139+
{ message = "^ci", group = "CI/CD" },
140+
{ message = "^chore", group = "Maintenance" },
141+
{ message = "^revert", group = "Reverts" },
122142
# === Regular Merge Commit Parsers (branch-based) ===
123143
# Features - check branch name patterns
124144
{ message = "^Merge pull request #[0-9]+ from .*/feat", group = "Features" },

0 commit comments

Comments
 (0)