Skip to content

Commit 4dd147d

Browse files
committed
feat: Add comprehensive GitHub Actions CI/CD pipeline
- CI workflow: multi-OS builds (Ubuntu, Windows, macOS), tests, formatting, clippy - Release workflow: automated releases with cross-platform binaries - Dependency workflow: automated dependency updates and security audits - Docker workflow: container builds with security scanning - Added multi-stage Dockerfile with security best practices - Support for multiple architectures (x64, ARM64) - Automated publishing to crates.io and GitHub Container Registry
1 parent ac8bcae commit 4dd147d

File tree

6 files changed

+685
-0
lines changed

6 files changed

+685
-0
lines changed

.dockerignore

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Git
2+
.git
3+
.gitignore
4+
5+
# Target directory
6+
target/
7+
**/*.rs.bk
8+
9+
# IDE files
10+
.vscode/
11+
.idea/
12+
*.iml
13+
*.swp
14+
*.swo
15+
*~
16+
17+
# OS files
18+
.DS_Store
19+
Thumbs.db
20+
21+
# Documentation
22+
*.md
23+
docs/
24+
25+
# Test files
26+
test_*
27+
**/test_*
28+
29+
# Automation workspace
30+
vulfy-workspace/
31+
vulfy-exports/
32+
33+
# Results and logs
34+
*.json
35+
*.log
36+
37+
# Docker files (except Dockerfile)
38+
.dockerignore
39+
docker-compose.yml
40+
41+
# CI/CD
42+
.github/
43+
44+
# Other
45+
assets/
46+
automation-results.json
47+
vulfy-scan-result.json

.github/workflows/ci.yml

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main, master, feat/* ]
6+
pull_request:
7+
branches: [ main, master ]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
12+
jobs:
13+
test:
14+
name: Test Suite
15+
runs-on: ${{ matrix.os }}
16+
strategy:
17+
matrix:
18+
os: [ubuntu-latest, windows-latest, macos-latest]
19+
rust: [stable, beta]
20+
include:
21+
- os: ubuntu-latest
22+
rust: nightly
23+
24+
steps:
25+
- name: Checkout code
26+
uses: actions/checkout@v4
27+
28+
- name: Install Rust
29+
uses: dtolnay/rust-toolchain@master
30+
with:
31+
toolchain: ${{ matrix.rust }}
32+
33+
- name: Cache Cargo registry
34+
uses: actions/cache@v4
35+
with:
36+
path: |
37+
~/.cargo/registry
38+
~/.cargo/git
39+
target
40+
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
41+
restore-keys: |
42+
${{ runner.os }}-cargo-
43+
44+
- name: Install system dependencies (Ubuntu)
45+
if: matrix.os == 'ubuntu-latest'
46+
run: |
47+
sudo apt-get update
48+
sudo apt-get install -y libssl-dev pkg-config
49+
50+
- name: Install system dependencies (macOS)
51+
if: matrix.os == 'macos-latest'
52+
run: |
53+
brew install openssl
54+
echo "OPENSSL_ROOT_DIR=$(brew --prefix openssl)" >> $GITHUB_ENV
55+
56+
- name: Check formatting
57+
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest'
58+
run: cargo fmt --all -- --check
59+
60+
- name: Run Clippy
61+
if: matrix.rust == 'stable'
62+
run: cargo clippy --all-targets --all-features -- -D warnings
63+
64+
- name: Run tests
65+
run: cargo test --verbose --all-features
66+
67+
- name: Build release
68+
run: cargo build --release --verbose
69+
70+
build:
71+
name: Build Binaries
72+
runs-on: ${{ matrix.os }}
73+
needs: test
74+
strategy:
75+
matrix:
76+
include:
77+
- os: ubuntu-latest
78+
target: x86_64-unknown-linux-gnu
79+
binary-suffix: ""
80+
- os: windows-latest
81+
target: x86_64-pc-windows-msvc
82+
binary-suffix: ".exe"
83+
- os: macos-latest
84+
target: x86_64-apple-darwin
85+
binary-suffix: ""
86+
- os: macos-latest
87+
target: aarch64-apple-darwin
88+
binary-suffix: ""
89+
90+
steps:
91+
- name: Checkout code
92+
uses: actions/checkout@v4
93+
94+
- name: Install Rust
95+
uses: dtolnay/rust-toolchain@stable
96+
with:
97+
targets: ${{ matrix.target }}
98+
99+
- name: Cache Cargo registry
100+
uses: actions/cache@v4
101+
with:
102+
path: |
103+
~/.cargo/registry
104+
~/.cargo/git
105+
target
106+
key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}
107+
restore-keys: |
108+
${{ runner.os }}-${{ matrix.target }}-cargo-
109+
110+
- name: Install system dependencies (Ubuntu)
111+
if: matrix.os == 'ubuntu-latest'
112+
run: |
113+
sudo apt-get update
114+
sudo apt-get install -y libssl-dev pkg-config
115+
116+
- name: Install system dependencies (macOS)
117+
if: matrix.os == 'macos-latest'
118+
run: |
119+
brew install openssl
120+
echo "OPENSSL_ROOT_DIR=$(brew --prefix openssl)" >> $GITHUB_ENV
121+
122+
- name: Build binary
123+
run: cargo build --release --target ${{ matrix.target }}
124+
125+
- name: Upload binary (Unix)
126+
if: matrix.os != 'windows-latest'
127+
uses: actions/upload-artifact@v4
128+
with:
129+
name: vulfy-${{ matrix.target }}
130+
path: target/${{ matrix.target }}/release/vulfy
131+
132+
- name: Upload binary (Windows)
133+
if: matrix.os == 'windows-latest'
134+
uses: actions/upload-artifact@v4
135+
with:
136+
name: vulfy-${{ matrix.target }}
137+
path: target/${{ matrix.target }}/release/vulfy.exe
138+
139+
security-audit:
140+
name: Security Audit
141+
runs-on: ubuntu-latest
142+
steps:
143+
- name: Checkout code
144+
uses: actions/checkout@v4
145+
146+
- name: Install Rust
147+
uses: dtolnay/rust-toolchain@stable
148+
149+
- name: Install cargo-audit
150+
run: cargo install cargo-audit
151+
152+
- name: Run security audit
153+
run: cargo audit
154+
155+
coverage:
156+
name: Code Coverage
157+
runs-on: ubuntu-latest
158+
steps:
159+
- name: Checkout code
160+
uses: actions/checkout@v4
161+
162+
- name: Install Rust
163+
uses: dtolnay/rust-toolchain@stable
164+
with:
165+
components: llvm-tools-preview
166+
167+
- name: Install system dependencies
168+
run: |
169+
sudo apt-get update
170+
sudo apt-get install -y libssl-dev pkg-config
171+
172+
- name: Install cargo-llvm-cov
173+
run: cargo install cargo-llvm-cov
174+
175+
- name: Generate coverage report
176+
run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
177+
178+
- name: Upload coverage to Codecov
179+
uses: codecov/codecov-action@v4
180+
with:
181+
file: lcov.info
182+
fail_ci_if_error: true
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
name: Dependency Update
2+
3+
on:
4+
schedule:
5+
# Run weekly on Monday at 9 AM UTC
6+
- cron: '0 9 * * 1'
7+
workflow_dispatch: # Allow manual trigger
8+
9+
jobs:
10+
update-dependencies:
11+
name: Update Dependencies
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@v4
16+
with:
17+
token: ${{ secrets.GITHUB_TOKEN }}
18+
19+
- name: Install Rust
20+
uses: dtolnay/rust-toolchain@stable
21+
22+
- name: Install system dependencies
23+
run: |
24+
sudo apt-get update
25+
sudo apt-get install -y libssl-dev pkg-config
26+
27+
- name: Install cargo-edit
28+
run: cargo install cargo-edit
29+
30+
- name: Update Cargo dependencies
31+
run: |
32+
cargo update
33+
cargo upgrade --incompatible
34+
35+
- name: Check if dependencies changed
36+
id: changes
37+
run: |
38+
if git diff --quiet Cargo.toml Cargo.lock; then
39+
echo "changed=false" >> $GITHUB_OUTPUT
40+
else
41+
echo "changed=true" >> $GITHUB_OUTPUT
42+
fi
43+
44+
- name: Run tests with updated dependencies
45+
if: steps.changes.outputs.changed == 'true'
46+
run: cargo test --all-features
47+
48+
- name: Create Pull Request
49+
if: steps.changes.outputs.changed == 'true'
50+
uses: peter-evans/create-pull-request@v5
51+
with:
52+
token: ${{ secrets.GITHUB_TOKEN }}
53+
commit-message: "chore: update dependencies"
54+
title: "🔄 Weekly Dependency Update"
55+
body: |
56+
## Dependency Update
57+
58+
This is an automated PR to update Rust dependencies.
59+
60+
### Changes
61+
- Updated `Cargo.lock` with latest compatible versions
62+
- Upgraded incompatible dependencies in `Cargo.toml`
63+
64+
### Testing
65+
- ✅ All tests pass with updated dependencies
66+
- ✅ Build succeeds on multiple platforms
67+
68+
### Review Notes
69+
Please review the changes and ensure all functionality works as expected.
70+
branch: dependency-update
71+
delete-branch: true
72+
73+
security-advisory:
74+
name: Security Advisory Check
75+
runs-on: ubuntu-latest
76+
steps:
77+
- name: Checkout code
78+
uses: actions/checkout@v4
79+
80+
- name: Install Rust
81+
uses: dtolnay/rust-toolchain@stable
82+
83+
- name: Install cargo-audit
84+
run: cargo install cargo-audit
85+
86+
- name: Run security audit
87+
run: cargo audit --json > audit-report.json || true
88+
89+
- name: Check for vulnerabilities
90+
id: vulnerabilities
91+
run: |
92+
if [ -s audit-report.json ] && jq '.vulnerabilities | length > 0' audit-report.json | grep -q true; then
93+
echo "found=true" >> $GITHUB_OUTPUT
94+
echo "## Security Vulnerabilities Found" >> vulnerability-report.md
95+
echo "" >> vulnerability-report.md
96+
jq -r '.vulnerabilities[] | "- **\(.advisory.id)**: \(.advisory.title) (Package: \(.package.name))"' audit-report.json >> vulnerability-report.md
97+
else
98+
echo "found=false" >> $GITHUB_OUTPUT
99+
fi
100+
101+
- name: Create Security Issue
102+
if: steps.vulnerabilities.outputs.found == 'true'
103+
uses: actions/github-script@v7
104+
with:
105+
script: |
106+
const fs = require('fs');
107+
const report = fs.readFileSync('vulnerability-report.md', 'utf8');
108+
109+
await github.rest.issues.create({
110+
owner: context.repo.owner,
111+
repo: context.repo.repo,
112+
title: '🚨 Security Vulnerabilities Detected',
113+
body: `${report}\n\n**Action Required**: Please review and update the affected dependencies.\n\nGenerated by: ${context.workflow} workflow`,
114+
labels: ['security', 'dependencies', 'urgent']
115+
});
116+
117+
outdated-check:
118+
name: Check Outdated Dependencies
119+
runs-on: ubuntu-latest
120+
steps:
121+
- name: Checkout code
122+
uses: actions/checkout@v4
123+
124+
- name: Install Rust
125+
uses: dtolnay/rust-toolchain@stable
126+
127+
- name: Install system dependencies
128+
run: |
129+
sudo apt-get update
130+
sudo apt-get install -y libssl-dev pkg-config
131+
132+
- name: Install cargo-outdated
133+
run: cargo install cargo-outdated
134+
135+
- name: Check for outdated dependencies
136+
run: |
137+
cargo outdated --format json > outdated.json || true
138+
echo "## Outdated Dependencies Report" > outdated-report.md
139+
echo "" >> outdated-report.md
140+
141+
if [ -s outdated.json ]; then
142+
jq -r '.dependencies[] | select(.latest != .project) | "- **\(.name)**: \(.project) → \(.latest)"' outdated.json >> outdated-report.md
143+
else
144+
echo "All dependencies are up to date! 🎉" >> outdated-report.md
145+
fi
146+
147+
- name: Upload outdated report
148+
uses: actions/upload-artifact@v4
149+
with:
150+
name: outdated-dependencies-report
151+
path: outdated-report.md

0 commit comments

Comments
 (0)