Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/mlc_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"ignorePatterns": [
{
"pattern": "^http://localhost"
},
{
"pattern": "^https://localhost"
}
],
"replacementPatterns": [],
"httpHeaders": [
{
"urls": ["https://crates.io", "https://docs.rs"],
"headers": {
"User-Agent": "Mozilla/5.0 (compatible; link-checker)"
}
}
],
"timeout": "10s",
"retryOn429": true,
"retryCount": 3,
"fallbackHttpStatus": [400, 401, 403, 404, 429, 500, 502, 503, 504]
}
112 changes: 112 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: CI

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]

env:
CARGO_TERM_COLOR: always

jobs:
test:
name: Test
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
- beta
- nightly

steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
components: rustfmt, clippy

- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-

- name: Check formatting
if: matrix.rust == 'stable'
run: cargo fmt --all -- --check

- name: Run clippy
if: matrix.rust == 'stable'
run: cargo clippy --all-targets --all-features -- -D warnings

- name: Build
run: cargo build --verbose --all-features

- name: Run tests
run: cargo test --verbose --all-features

- name: Test CLI
run: |
cargo run -- --help
cargo run -- check --help
cargo run -- rules

coverage:
name: Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov

- name: Generate code coverage
run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
file: lcov.info
fail_ci_if_error: true

security:
name: Security Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Install cargo-audit
run: cargo install cargo-audit

- name: Run security audit
run: cargo audit

minimal-versions:
name: Minimal Versions
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@nightly

- name: Install minimal-versions
run: cargo install cargo-minimal-versions

- name: Check minimal versions
run: cargo minimal-versions check
95 changes: 95 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Documentation

on:
push:
branches: [ main ]
paths:
- 'src/**'
- 'README.md'
- 'Cargo.toml'
- 'examples/**'
pull_request:
branches: [ main ]
paths:
- 'src/**'
- 'README.md'
- 'Cargo.toml'
- 'examples/**'

env:
CARGO_TERM_COLOR: always

jobs:
doc-tests:
name: Documentation Tests
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-

- name: Test documentation examples
run: cargo test --doc --all-features

- name: Build documentation
run: |
cargo doc --all-features --no-deps
# Check that docs build without warnings
cargo doc --all-features --no-deps 2>&1 | tee doc-warnings.txt
if grep -q "warning:" doc-warnings.txt; then
echo "Documentation has warnings!"
cat doc-warnings.txt
exit 1
fi

- name: Check README examples
run: |
# Extract and test code examples from README
echo "Checking README examples compile..."
# This is a basic check - in practice you might want more sophisticated validation

check-links:
name: Check Documentation Links
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Check links in README
uses: gaurav-nelson/github-action-markdown-link-check@v1
with:
use-quiet-mode: 'yes'
use-verbose-mode: 'yes'
config-file: '.github/mlc_config.json'

Copilot AI Aug 10, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The markdown link checker config file path should be referenced without quotes to ensure proper file resolution.

Suggested change
config-file: '.github/mlc_config.json'
config-file: .github/mlc_config.json

Copilot uses AI. Check for mistakes.

validate-metadata:
name: Validate Package Metadata
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Check package metadata
run: |
# Verify all required metadata is present for crates.io
echo "Checking package metadata..."
cargo metadata --format-version 1 | jq -r '.packages[] | select(.name == "rust-guardian") | {name, version, description, license, repository, documentation, keywords, categories}'

# Verify the package can be packaged (list files)
cargo package --list --allow-dirty
160 changes: 160 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
name: Release

on:
push:
tags:
- 'v*'

env:
CARGO_TERM_COLOR: always

jobs:
pre-release-checks:
name: Pre-release Checks
runs-on: ubuntu-latest
outputs:
version: ${{ steps.get_version.outputs.version }}

steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

- name: Get version from tag
id: get_version
run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT

- name: Verify version matches Cargo.toml
run: |
CARGO_VERSION=$(grep "^version = " Cargo.toml | sed 's/version = "\(.*\)"/\1/')
if [ "$CARGO_VERSION" != "${{ steps.get_version.outputs.version }}" ]; then
echo "Version mismatch: Cargo.toml has $CARGO_VERSION but tag is ${{ steps.get_version.outputs.version }}"
exit 1
fi

- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-

- name: Check formatting
run: cargo fmt --all -- --check

- name: Run clippy
run: cargo clippy --all-targets --all-features -- -D warnings

- name: Build
run: cargo build --verbose --all-features

- name: Run tests
run: cargo test --verbose --all-features

- name: Test CLI functionality
run: |
cargo run -- --help
cargo run -- check --help
cargo run -- rules

publish-crates-io:
name: Publish to crates.io
needs: pre-release-checks
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-

- name: Publish to crates.io
run: cargo publish --token ${{ secrets.CRATES_TOKEN }}

create-github-release:
name: Create GitHub Release
needs: [pre-release-checks, publish-crates-io]
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Build release binaries
run: |
# Build for different targets
cargo build --release --all-features

# Create release directory
mkdir -p release-artifacts

# Copy binary and create archive
cp target/release/rust-guardian release-artifacts/
tar -czf release-artifacts/rust-guardian-${{ needs.pre-release-checks.outputs.version }}-x86_64-unknown-linux-gnu.tar.gz -C release-artifacts rust-guardian

# Generate checksums
cd release-artifacts
sha256sum * > checksums.txt

- name: Generate changelog
id: changelog
run: |
# Try to get changelog from git log since last tag
PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
if [ -n "$PREVIOUS_TAG" ]; then
echo "## Changes since $PREVIOUS_TAG" > CHANGELOG.md
git log --pretty=format:"- %s (%h)" ${PREVIOUS_TAG}..HEAD >> CHANGELOG.md
else
echo "## Release ${{ needs.pre-release-checks.outputs.version }}" > CHANGELOG.md
echo "Initial release of rust-guardian" >> CHANGELOG.md
fi

# Add installation instructions
echo "" >> CHANGELOG.md
echo "## Installation" >> CHANGELOG.md
echo "" >> CHANGELOG.md
echo "\`\`\`bash" >> CHANGELOG.md
echo "cargo install rust-guardian" >> CHANGELOG.md
echo "\`\`\`" >> CHANGELOG.md
echo "" >> CHANGELOG.md
echo "## Documentation" >> CHANGELOG.md
echo "" >> CHANGELOG.md
echo "- [Crates.io](https://crates.io/crates/rust-guardian)" >> CHANGELOG.md
echo "- [Documentation](https://docs.rs/rust-guardian)" >> CHANGELOG.md
echo "- [Repository](https://github.com/cloudfunnels/rust-guardian)" >> CHANGELOG.md

- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.pre-release-checks.outputs.version }}
name: Release v${{ needs.pre-release-checks.outputs.version }}
body_path: CHANGELOG.md

Copilot AI Aug 10, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Writing to CHANGELOG.md will overwrite the existing changelog file. This should write to a temporary file (e.g., RELEASE_NOTES.md) to avoid destroying the project's changelog history.

Suggested change
body_path: CHANGELOG.md
echo "## Changes since $PREVIOUS_TAG" > RELEASE_NOTES.md
git log --pretty=format:"- %s (%h)" ${PREVIOUS_TAG}..HEAD >> RELEASE_NOTES.md
else
echo "## Release ${{ needs.pre-release-checks.outputs.version }}" > RELEASE_NOTES.md
echo "Initial release of rust-guardian" >> RELEASE_NOTES.md
fi
# Add installation instructions
echo "" >> RELEASE_NOTES.md
echo "## Installation" >> RELEASE_NOTES.md
echo "" >> RELEASE_NOTES.md
echo "\`\`\`bash" >> RELEASE_NOTES.md
echo "cargo install rust-guardian" >> RELEASE_NOTES.md
echo "\`\`\`" >> RELEASE_NOTES.md
echo "" >> RELEASE_NOTES.md
echo "## Documentation" >> RELEASE_NOTES.md
echo "" >> RELEASE_NOTES.md
echo "- [Crates.io](https://crates.io/crates/rust-guardian)" >> RELEASE_NOTES.md
echo "- [Documentation](https://docs.rs/rust-guardian)" >> RELEASE_NOTES.md
echo "- [Repository](https://github.com/cloudfunnels/rust-guardian)" >> RELEASE_NOTES.md
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.pre-release-checks.outputs.version }}
name: Release v${{ needs.pre-release-checks.outputs.version }}
body_path: RELEASE_NOTES.md

Copilot uses AI. Check for mistakes.
files: |
release-artifacts/*.tar.gz
release-artifacts/checksums.txt
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Loading
Loading