Skip to content

Commit 04821c6

Browse files
authored
Merge pull request #13 from linksplatform/issue-12-ac77ef01d187
feat: apply latest best practices from Rust template
2 parents edb6760 + 0c2c32e commit 04821c6

18 files changed

+1122
-631
lines changed

.github/workflows/release.yml

Lines changed: 69 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ concurrency:
2727

2828
env:
2929
CARGO_TERM_COLOR: always
30+
RUSTFLAGS: -Dwarnings
3031

3132
jobs:
3233
# REQUIRED CI CHECKS - All must pass before release
@@ -44,6 +45,11 @@ jobs:
4445
with:
4546
components: rustfmt, clippy
4647

48+
- name: Setup Node.js
49+
uses: actions/setup-node@v4
50+
with:
51+
node-version: '20.x'
52+
4753
- name: Cache cargo registry
4854
uses: actions/cache@v4
4955
with:
@@ -59,10 +65,10 @@ jobs:
5965
run: cargo fmt --all -- --check
6066

6167
- name: Run Clippy
62-
run: cargo clippy --all-targets --all-features -- -D warnings
68+
run: cargo clippy --all-targets --all-features
6369

6470
- name: Check file size limit
65-
run: python3 scripts/check_file_size.py
71+
run: node scripts/check-file-size.mjs
6672

6773
# Test on multiple OS
6874
test:
@@ -140,11 +146,11 @@ jobs:
140146
141147
echo "Coverage check passed: $COVERAGE% >= 90%"
142148
143-
# Build package - only runs if lint, test, and coverage pass
149+
# Build package - only runs if lint and test pass
144150
build:
145151
name: Build Package
146152
runs-on: ubuntu-latest
147-
needs: [lint, test, coverage]
153+
needs: [lint, test]
148154
steps:
149155
- uses: actions/checkout@v4
150156

@@ -203,7 +209,8 @@ jobs:
203209
204210
echo "Changelog check passed"
205211
206-
# Automatic release on push to main (if version changed)
212+
# Automatic release on push to main using changelog fragments
213+
# This job automatically bumps version based on fragments in changelog.d/
207214
auto-release:
208215
name: Auto Release
209216
needs: [lint, test, build]
@@ -215,37 +222,71 @@ jobs:
215222
- uses: actions/checkout@v4
216223
with:
217224
fetch-depth: 0
225+
token: ${{ secrets.GITHUB_TOKEN }}
218226

219227
- name: Setup Rust
220228
uses: dtolnay/rust-toolchain@stable
221229

222-
- name: Check if version changed
223-
id: version_check
230+
- name: Setup Node.js
231+
uses: actions/setup-node@v4
232+
with:
233+
node-version: '20.x'
234+
235+
- name: Configure git
224236
run: |
225-
# Get current version from Cargo.toml
226-
CURRENT_VERSION=$(grep -Po '(?<=^version = ")[^"]*' Cargo.toml)
227-
echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
237+
git config user.name "github-actions[bot]"
238+
git config user.email "github-actions[bot]@users.noreply.github.com"
239+
240+
- name: Determine bump type from changelog fragments
241+
id: bump_type
242+
run: node scripts/get-bump-type.mjs
228243

229-
# Check if tag exists
230-
if git rev-parse "v$CURRENT_VERSION" >/dev/null 2>&1; then
231-
echo "Tag v$CURRENT_VERSION already exists, skipping release"
232-
echo "should_release=false" >> $GITHUB_OUTPUT
244+
- name: Check if version already released or no fragments
245+
id: check
246+
run: |
247+
# Check if there are changelog fragments
248+
if [ "${{ steps.bump_type.outputs.has_fragments }}" != "true" ]; then
249+
# No fragments - check if current version tag exists
250+
CURRENT_VERSION=$(grep -Po '(?<=^version = ")[^"]*' Cargo.toml)
251+
if git rev-parse "v$CURRENT_VERSION" >/dev/null 2>&1; then
252+
echo "No changelog fragments and v$CURRENT_VERSION already released"
253+
echo "should_release=false" >> $GITHUB_OUTPUT
254+
else
255+
echo "No changelog fragments but v$CURRENT_VERSION not yet released"
256+
echo "should_release=true" >> $GITHUB_OUTPUT
257+
echo "skip_bump=true" >> $GITHUB_OUTPUT
258+
fi
233259
else
234-
echo "New version detected: $CURRENT_VERSION"
260+
echo "Found changelog fragments, proceeding with release"
235261
echo "should_release=true" >> $GITHUB_OUTPUT
262+
echo "skip_bump=false" >> $GITHUB_OUTPUT
236263
fi
237264
265+
- name: Collect changelog and bump version
266+
id: version
267+
if: steps.check.outputs.should_release == 'true' && steps.check.outputs.skip_bump != 'true'
268+
run: |
269+
node scripts/version-and-commit.mjs \
270+
--bump-type "${{ steps.bump_type.outputs.bump_type }}"
271+
272+
- name: Get current version
273+
id: current_version
274+
if: steps.check.outputs.should_release == 'true'
275+
run: |
276+
CURRENT_VERSION=$(grep -Po '(?<=^version = ")[^"]*' Cargo.toml)
277+
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
278+
238279
- name: Build release
239-
if: steps.version_check.outputs.should_release == 'true'
280+
if: steps.check.outputs.should_release == 'true'
240281
run: cargo build --release
241282

242283
- name: Create GitHub Release
243-
if: steps.version_check.outputs.should_release == 'true'
284+
if: steps.check.outputs.should_release == 'true'
244285
env:
245286
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
246287
run: |
247-
python3 scripts/create_github_release.py \
248-
--version "${{ steps.version_check.outputs.current_version }}" \
288+
node scripts/create-github-release.mjs \
289+
--release-version "${{ steps.current_version.outputs.version }}" \
249290
--repository "${{ github.repository }}"
250291
251292
# Manual release via workflow_dispatch - only after CI passes
@@ -265,6 +306,11 @@ jobs:
265306
- name: Setup Rust
266307
uses: dtolnay/rust-toolchain@stable
267308

309+
- name: Setup Node.js
310+
uses: actions/setup-node@v4
311+
with:
312+
node-version: '20.x'
313+
268314
- name: Configure git
269315
run: |
270316
git config user.name "github-actions[bot]"
@@ -276,15 +322,15 @@ jobs:
276322
FRAGMENTS=$(find changelog.d -name "*.md" ! -name "README.md" 2>/dev/null | wc -l)
277323
if [ "$FRAGMENTS" -gt 0 ]; then
278324
echo "Found $FRAGMENTS changelog fragment(s), collecting..."
279-
python3 scripts/collect_changelog.py
325+
node scripts/collect-changelog.mjs
280326
else
281327
echo "No changelog fragments found, skipping collection"
282328
fi
283329
284330
- name: Version and commit
285331
id: version
286332
run: |
287-
python3 scripts/version_and_commit.py \
333+
node scripts/version-and-commit.mjs \
288334
--bump-type "${{ github.event.inputs.bump_type }}" \
289335
--description "${{ github.event.inputs.description }}"
290336
@@ -297,6 +343,6 @@ jobs:
297343
env:
298344
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
299345
run: |
300-
python3 scripts/create_github_release.py \
301-
--version "${{ steps.version.outputs.new_version }}" \
346+
node scripts/create-github-release.mjs \
347+
--release-version "${{ steps.version.outputs.new_version }}" \
302348
--repository "${{ github.repository }}"

CONTRIBUTING.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ Thank you for your interest in contributing! This document provides guidelines a
6262
cargo clippy --all-targets --all-features
6363

6464
# Check file sizes
65-
python3 scripts/check_file_size.py
65+
node scripts/check-file-size.mjs
6666

6767
# Run all checks together
68-
cargo fmt --check && cargo clippy --all-targets --all-features && python3 scripts/check_file_size.py
68+
cargo fmt --check && cargo clippy --all-targets --all-features && node scripts/check-file-size.mjs
6969
```
7070

7171
4. **Run tests**
@@ -94,17 +94,21 @@ Thank you for your interest in contributing! This document provides guidelines a
9494
touch changelog.d/$(date +%Y%m%d_%H%M%S)_my_change.md
9595
```
9696

97-
Edit the file to document your changes:
97+
Edit the file to document your changes with a bump type in the frontmatter:
9898

9999
```markdown
100+
---
101+
bump: minor
102+
---
103+
100104
### Added
101105
- Description of new feature
102106

103107
### Fixed
104108
- Description of bug fix
105109
```
106110

107-
**Why fragments?** This prevents merge conflicts in CHANGELOG.md when multiple PRs are open simultaneously.
111+
**Why fragments?** This prevents merge conflicts in CHANGELOG.md when multiple PRs are open simultaneously. The bump type (`major`, `minor`, or `patch`) in the frontmatter enables automatic version bumping during release.
108112

109113
6. **Commit your changes**
110114

changelog.d/20251227_100_coverage.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
bump: minor
3+
---
4+
15
### Added
26
- Test coverage infrastructure using cargo-tarpaulin with 90% minimum threshold
37
- Comprehensive unit tests achieving 94.57% code coverage

changelog.d/20251227_173319_add_cicd_pipeline.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
bump: minor
3+
---
4+
15
### Added
26
- Modern CI/CD pipeline from rust-ai-driven-development-pipeline-template
37
- GitHub Actions workflow for automated testing, linting, and releases

changelog.d/20251227_183811_migrate_to_stable_rust.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
bump: major
3+
---
4+
15
### Changed
26
- Migrated from nightly Rust to **stable Rust** toolchain (requires Rust 1.79+)
37
- Removed all unstable feature flags:
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
bump: minor
3+
---
4+
5+
### Changed
6+
- Migrated all CI/CD scripts from Python to JavaScript ES modules (.mjs) for enhanced performance
7+
- Updated release workflow to use Node.js 20.x for script execution
8+
- Added automatic version bumping based on changelog fragment frontmatter
9+
10+
### Added
11+
- New `get-bump-type.mjs` script that parses changelog fragments and determines version bump type
12+
- Frontmatter support in changelog fragments with `bump: major|minor|patch` specification
13+
- Automatic version bumping during release based on highest priority bump type from fragments
14+
15+
### Documentation
16+
- Updated `changelog.d/README.md` with comprehensive frontmatter documentation and examples
17+
- Updated `CONTRIBUTING.md` with new script references and fragment format instructions

changelog.d/README.md

Lines changed: 89 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,34 @@ touch changelog.d/$(date +%Y%m%d_%H%M%S)_description.md
1515

1616
## Fragment Format
1717

18-
Each fragment should contain relevant sections. Use the appropriate sections:
18+
Each fragment should include a **frontmatter section** specifying the version bump type:
1919

2020
```markdown
21+
---
22+
bump: patch
23+
---
24+
25+
### Fixed
26+
- Description of bug fix
27+
```
28+
29+
### Bump Types
30+
31+
Use semantic versioning bump types in the frontmatter:
32+
33+
- **`major`**: Breaking changes (incompatible API changes)
34+
- **`minor`**: New features (backward compatible)
35+
- **`patch`**: Bug fixes (backward compatible)
36+
37+
### Content Categories
38+
39+
Use these categories in your fragment content:
40+
41+
```markdown
42+
---
43+
bump: minor
44+
---
45+
2146
### Added
2247
- Description of new feature
2348

@@ -37,15 +62,74 @@ Each fragment should contain relevant sections. Use the appropriate sections:
3762
- Description of security fix
3863
```
3964

65+
## Examples
66+
67+
### Adding a new feature (minor bump)
68+
69+
```markdown
70+
---
71+
bump: minor
72+
---
73+
74+
### Added
75+
- New async processing mode for batch operations
76+
```
77+
78+
### Fixing a bug (patch bump)
79+
80+
```markdown
81+
---
82+
bump: patch
83+
---
84+
85+
### Fixed
86+
- Fixed memory leak in connection pool handling
87+
```
88+
89+
### Breaking change (major bump)
90+
91+
```markdown
92+
---
93+
bump: major
94+
---
95+
96+
### Changed
97+
- Renamed `process()` to `process_async()` - this is a breaking change
98+
99+
### Removed
100+
- Removed deprecated `legacy_mode` option
101+
```
102+
40103
## Why Fragments?
41104

42105
Using changelog fragments (similar to [Changesets](https://github.com/changesets/changesets) in JavaScript and [Scriv](https://scriv.readthedocs.io/) in Python):
43106

44107
1. **No merge conflicts**: Multiple PRs can add fragments without conflicts
45108
2. **Per-PR documentation**: Each PR documents its own changes
46-
3. **Automated collection**: Fragments are automatically collected during release
47-
4. **Consistent format**: Template ensures consistent changelog entries
109+
3. **Automated version bumping**: Version bump type is specified per-change
110+
4. **Automated collection**: Fragments are automatically collected during release
111+
5. **Consistent format**: Template ensures consistent changelog entries
112+
113+
## How It Works
114+
115+
1. **During PR**: Add a fragment file with your changes and bump type
116+
2. **On merge to main**: The release workflow automatically:
117+
- Reads all fragment files and determines the highest bump type
118+
- Bumps the version in `Cargo.toml` accordingly
119+
- Collects fragments into `CHANGELOG.md`
120+
- Creates a git tag and GitHub release
121+
- Removes processed fragment files
122+
123+
## Multiple PRs and Bump Priority
124+
125+
When multiple PRs are merged before a release, all pending fragments are processed together. The **highest** bump type wins:
126+
127+
- If any fragment specifies `major`, the release is a major version bump
128+
- Otherwise, if any specifies `minor`, the release is a minor version bump
129+
- Otherwise, the release is a patch version bump
130+
131+
This ensures that breaking changes are never missed, even when combined with smaller changes.
48132

49-
## During Release
133+
## Default Behavior
50134

51-
Fragments are automatically collected into `CHANGELOG.md` by running the collection script. This is handled automatically by the release workflow.
135+
If a fragment doesn't include a bump type in the frontmatter, it defaults to `patch`.

0 commit comments

Comments
 (0)