Skip to content

Commit f38a611

Browse files
authored
Merge pull request #124 from linksplatform/issue-123-ca4a6bfb3f29
100% tests coverage for Rust version
2 parents bd5e442 + 0cfa879 commit f38a611

17 files changed

+2367
-10
lines changed

.github/workflows/rust.yml

Lines changed: 364 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,364 @@
1+
name: Rust CI/CD Pipeline
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'rust/**'
9+
- '.github/workflows/rust.yml'
10+
- 'scripts/**'
11+
- 'changelog.d/**'
12+
pull_request:
13+
types: [opened, synchronize, reopened]
14+
paths:
15+
- 'rust/**'
16+
- '.github/workflows/rust.yml'
17+
- 'scripts/**'
18+
- 'changelog.d/**'
19+
workflow_dispatch:
20+
inputs:
21+
bump_type:
22+
description: 'Version bump type'
23+
required: true
24+
type: choice
25+
options:
26+
- patch
27+
- minor
28+
- major
29+
description:
30+
description: 'Release description (optional)'
31+
required: false
32+
type: string
33+
34+
concurrency:
35+
group: ${{ github.workflow }}-${{ github.ref }}
36+
cancel-in-progress: true
37+
38+
env:
39+
CARGO_TERM_COLOR: always
40+
41+
defaults:
42+
run:
43+
working-directory: rust
44+
45+
jobs:
46+
# REQUIRED CI CHECKS - All must pass before release
47+
# These jobs ensure code quality and tests pass before any release
48+
49+
# Linting and formatting
50+
lint:
51+
name: Lint and Format Check
52+
runs-on: ubuntu-latest
53+
steps:
54+
- uses: actions/checkout@v4
55+
56+
- name: Install Rust toolchain
57+
uses: dtolnay/rust-toolchain@master
58+
with:
59+
toolchain: nightly-2022-08-22
60+
components: rustfmt
61+
62+
- name: Setup Node.js
63+
uses: actions/setup-node@v4
64+
with:
65+
node-version: '20.x'
66+
67+
- name: Cache cargo registry
68+
uses: actions/cache@v4
69+
with:
70+
path: |
71+
~/.cargo/registry
72+
~/.cargo/git
73+
rust/target
74+
key: ${{ runner.os }}-cargo-${{ hashFiles('rust/Cargo.lock') }}
75+
restore-keys: |
76+
${{ runner.os }}-cargo-
77+
78+
- name: Check formatting
79+
run: cargo fmt --all -- --check
80+
81+
- name: Check file size limit
82+
working-directory: .
83+
run: node scripts/check-file-size.mjs
84+
85+
# Test on multiple OS
86+
test:
87+
name: Test (${{ matrix.os }})
88+
runs-on: ${{ matrix.os }}
89+
strategy:
90+
fail-fast: false
91+
matrix:
92+
os: [ubuntu-latest, macos-latest, windows-latest]
93+
steps:
94+
- uses: actions/checkout@v4
95+
96+
- name: Install Rust toolchain
97+
uses: dtolnay/rust-toolchain@master
98+
with:
99+
toolchain: nightly-2022-08-22
100+
101+
- name: Cache cargo registry
102+
uses: actions/cache@v4
103+
with:
104+
path: |
105+
~/.cargo/registry
106+
~/.cargo/git
107+
rust/target
108+
key: ${{ runner.os }}-cargo-${{ hashFiles('rust/Cargo.lock') }}
109+
restore-keys: |
110+
${{ runner.os }}-cargo-
111+
112+
- name: Run tests
113+
run: cargo test --all-features --verbose
114+
115+
# Code coverage
116+
coverage:
117+
name: Code Coverage
118+
runs-on: ubuntu-latest
119+
steps:
120+
- uses: actions/checkout@v4
121+
122+
- name: Install Rust toolchain
123+
uses: dtolnay/rust-toolchain@master
124+
with:
125+
toolchain: nightly-2022-08-22
126+
components: llvm-tools-preview
127+
128+
- name: Cache cargo registry
129+
uses: actions/cache@v4
130+
with:
131+
path: |
132+
~/.cargo/registry
133+
~/.cargo/git
134+
rust/target
135+
key: ${{ runner.os }}-cargo-coverage-${{ hashFiles('rust/Cargo.lock') }}
136+
restore-keys: |
137+
${{ runner.os }}-cargo-coverage-
138+
139+
- name: Install cargo-llvm-cov
140+
uses: taiki-e/install-action@cargo-llvm-cov
141+
142+
- name: Generate code coverage
143+
run: cargo llvm-cov --all-features --lcov --output-path lcov.info
144+
145+
- name: Upload coverage to Codecov
146+
uses: codecov/codecov-action@v4
147+
with:
148+
files: rust/lcov.info
149+
fail_ci_if_error: false
150+
151+
# Build package - only runs if lint and test pass
152+
build:
153+
name: Build Package
154+
runs-on: ubuntu-latest
155+
needs: [lint, test]
156+
steps:
157+
- uses: actions/checkout@v4
158+
159+
- name: Install Rust toolchain
160+
uses: dtolnay/rust-toolchain@master
161+
with:
162+
toolchain: nightly-2022-08-22
163+
164+
- name: Cache cargo registry
165+
uses: actions/cache@v4
166+
with:
167+
path: |
168+
~/.cargo/registry
169+
~/.cargo/git
170+
rust/target
171+
key: ${{ runner.os }}-cargo-build-${{ hashFiles('rust/Cargo.lock') }}
172+
restore-keys: |
173+
${{ runner.os }}-cargo-build-
174+
175+
- name: Build release
176+
run: cargo build --release --verbose
177+
178+
# Check for changelog fragments in PRs
179+
changelog:
180+
name: Changelog Fragment Check
181+
runs-on: ubuntu-latest
182+
if: github.event_name == 'pull_request'
183+
steps:
184+
- uses: actions/checkout@v4
185+
with:
186+
fetch-depth: 0
187+
188+
- name: Check for changelog fragments
189+
working-directory: .
190+
run: |
191+
# Get list of fragment files (excluding README and template)
192+
FRAGMENTS=$(find changelog.d -name "*.md" ! -name "README.md" 2>/dev/null | wc -l)
193+
194+
# Get changed files in PR
195+
CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)
196+
197+
# Check if any source files changed (excluding docs and config)
198+
SOURCE_CHANGED=$(echo "$CHANGED_FILES" | grep -E "^(rust/src/|rust/tests/|scripts/)" | wc -l)
199+
200+
if [ "$SOURCE_CHANGED" -gt 0 ] && [ "$FRAGMENTS" -eq 0 ]; then
201+
echo "::warning::No changelog fragment found. Please add a changelog entry in changelog.d/"
202+
echo ""
203+
echo "To create a changelog fragment:"
204+
echo " Create a new .md file in changelog.d/ with your changes"
205+
echo ""
206+
echo "See changelog.d/README.md for more information."
207+
# Note: This is a warning, not a failure, to allow flexibility
208+
# Change 'exit 0' to 'exit 1' to make it required
209+
exit 0
210+
fi
211+
212+
echo "Changelog check passed"
213+
214+
# Automatic release on push to main using changelog fragments
215+
# This job automatically bumps version based on fragments in changelog.d/
216+
auto-release:
217+
name: Auto Release
218+
needs: [lint, test, build, coverage]
219+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
220+
runs-on: ubuntu-latest
221+
permissions:
222+
contents: write
223+
steps:
224+
- uses: actions/checkout@v4
225+
with:
226+
fetch-depth: 0
227+
token: ${{ secrets.GITHUB_TOKEN }}
228+
229+
- name: Install Rust toolchain
230+
uses: dtolnay/rust-toolchain@master
231+
with:
232+
toolchain: nightly-2022-08-22
233+
234+
- name: Setup Node.js
235+
uses: actions/setup-node@v4
236+
with:
237+
node-version: '20.x'
238+
239+
- name: Configure git
240+
run: |
241+
git config user.name "github-actions[bot]"
242+
git config user.email "github-actions[bot]@users.noreply.github.com"
243+
working-directory: .
244+
245+
- name: Determine bump type from changelog fragments
246+
id: bump_type
247+
working-directory: .
248+
run: node scripts/get-bump-type.mjs
249+
250+
- name: Check if version already released or no fragments
251+
id: check
252+
working-directory: .
253+
run: |
254+
# Check if there are changelog fragments
255+
if [ "${{ steps.bump_type.outputs.has_fragments }}" != "true" ]; then
256+
# No fragments - check if current version tag exists
257+
CURRENT_VERSION=$(grep -Po '(?<=^version = ")[^"]*' rust/Cargo.toml)
258+
if git rev-parse "v$CURRENT_VERSION" >/dev/null 2>&1; then
259+
echo "No changelog fragments and v$CURRENT_VERSION already released"
260+
echo "should_release=false" >> $GITHUB_OUTPUT
261+
else
262+
echo "No changelog fragments but v$CURRENT_VERSION not yet released"
263+
echo "should_release=true" >> $GITHUB_OUTPUT
264+
echo "skip_bump=true" >> $GITHUB_OUTPUT
265+
fi
266+
else
267+
echo "Found changelog fragments, proceeding with release"
268+
echo "should_release=true" >> $GITHUB_OUTPUT
269+
echo "skip_bump=false" >> $GITHUB_OUTPUT
270+
fi
271+
272+
- name: Collect changelog and bump version
273+
id: version
274+
if: steps.check.outputs.should_release == 'true' && steps.check.outputs.skip_bump != 'true'
275+
working-directory: .
276+
run: |
277+
node scripts/version-and-commit.mjs \
278+
--bump-type "${{ steps.bump_type.outputs.bump_type }}"
279+
280+
- name: Get current version
281+
id: current_version
282+
if: steps.check.outputs.should_release == 'true'
283+
working-directory: .
284+
run: |
285+
CURRENT_VERSION=$(grep -Po '(?<=^version = ")[^"]*' rust/Cargo.toml)
286+
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
287+
288+
- name: Build release
289+
if: steps.check.outputs.should_release == 'true'
290+
run: cargo build --release
291+
292+
- name: Create GitHub Release
293+
if: steps.check.outputs.should_release == 'true'
294+
env:
295+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
296+
working-directory: .
297+
run: |
298+
node scripts/create-github-release.mjs \
299+
--release-version "${{ steps.current_version.outputs.version }}" \
300+
--repository "${{ github.repository }}"
301+
302+
# Manual release via workflow_dispatch - only after CI passes
303+
manual-release:
304+
name: Manual Release
305+
needs: [lint, test, build, coverage]
306+
if: github.event_name == 'workflow_dispatch'
307+
runs-on: ubuntu-latest
308+
permissions:
309+
contents: write
310+
steps:
311+
- uses: actions/checkout@v4
312+
with:
313+
fetch-depth: 0
314+
token: ${{ secrets.GITHUB_TOKEN }}
315+
316+
- name: Install Rust toolchain
317+
uses: dtolnay/rust-toolchain@master
318+
with:
319+
toolchain: nightly-2022-08-22
320+
321+
- name: Setup Node.js
322+
uses: actions/setup-node@v4
323+
with:
324+
node-version: '20.x'
325+
326+
- name: Configure git
327+
run: |
328+
git config user.name "github-actions[bot]"
329+
git config user.email "github-actions[bot]@users.noreply.github.com"
330+
working-directory: .
331+
332+
- name: Collect changelog fragments
333+
working-directory: .
334+
run: |
335+
# Check if there are any fragments to collect
336+
FRAGMENTS=$(find changelog.d -name "*.md" ! -name "README.md" 2>/dev/null | wc -l)
337+
if [ "$FRAGMENTS" -gt 0 ]; then
338+
echo "Found $FRAGMENTS changelog fragment(s), collecting..."
339+
node scripts/collect-changelog.mjs
340+
else
341+
echo "No changelog fragments found, skipping collection"
342+
fi
343+
344+
- name: Version and commit
345+
id: version
346+
working-directory: .
347+
run: |
348+
node scripts/version-and-commit.mjs \
349+
--bump-type "${{ github.event.inputs.bump_type }}" \
350+
--description "${{ github.event.inputs.description }}"
351+
352+
- name: Build release
353+
if: steps.version.outputs.version_committed == 'true' || steps.version.outputs.already_released == 'true'
354+
run: cargo build --release
355+
356+
- name: Create GitHub Release
357+
if: steps.version.outputs.version_committed == 'true' || steps.version.outputs.already_released == 'true'
358+
env:
359+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
360+
working-directory: .
361+
run: |
362+
node scripts/create-github-release.mjs \
363+
--release-version "${{ steps.version.outputs.new_version }}" \
364+
--repository "${{ github.repository }}"

0 commit comments

Comments
 (0)