Skip to content

Commit e5ea61e

Browse files
committed
feat: add CLI arguments, modular refactor, test reorganization, and security scanning
- Add CLI support with short/long options (-s/--size, -p/--profile, etc.) - Split diskmark.sh into lib/ modules (args, validate, utils, profiles, detect, benchmark, output, update) - Reorganize tests into 6 concurrent jobs with optimized timing (100ms/500ms) - Add security.yml workflow with Trivy and Grype vulnerability scanners
1 parent f8ed615 commit e5ea61e

15 files changed

Lines changed: 1818 additions & 1222 deletions

.github/copilot-instructions.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Copilot Instructions for docker-diskmark
2+
3+
## Project Overview
4+
5+
Docker DiskMark is a fio-based disk benchmarking tool packaged as a minimal Docker container. It provides CrystalDiskMark-like functionality for Linux systems.
6+
7+
## Project Structure
8+
9+
```
10+
diskmark.sh # Main entry point (~100 lines)
11+
lib/
12+
├── args.sh # CLI argument parsing + help/version
13+
├── validate.sh # Input validation functions
14+
├── utils.sh # Utility functions (color, size conversion, cleanup)
15+
├── profiles.sh # Profile definitions (default, nvme, custom job)
16+
├── detect.sh # Drive/filesystem detection
17+
├── benchmark.sh # fio benchmark execution + warmup + result parsing
18+
├── output.sh # Output formatting (human/JSON/YAML/XML)
19+
└── update.sh # Update check functionality
20+
```
21+
22+
## Clean Code Principles
23+
24+
Follow these clean code principles when contributing:
25+
26+
### Single Responsibility
27+
- Each function should do one thing and do it well
28+
- Keep functions small and focused (ideally < 30 lines)
29+
- Separate concerns: parsing, validation, execution, output
30+
31+
### Meaningful Names
32+
- Use descriptive function names: `validate_size_string` not `check`
33+
- Use consistent naming conventions (snake_case for functions/variables)
34+
- Prefix validation functions with `validate_`
35+
- Prefix parsing functions with `parse_`
36+
37+
### DRY (Don't Repeat Yourself)
38+
- Extract common patterns into reusable functions
39+
- Use helper functions for repeated validation logic
40+
- Centralize error handling and output formatting
41+
42+
### Comments and Documentation
43+
- Functions should be self-documenting through clear names
44+
- Add comments only when explaining "why", not "what"
45+
- Keep help text and documentation in sync with code
46+
47+
### Error Handling
48+
- Fail fast with clear error messages
49+
- Validate inputs early before processing
50+
- Use consistent exit codes (0=success, 1=error)
51+
52+
### Code Organization
53+
- Group related functions together
54+
- Order: constants → helpers → validators → core logic → main
55+
- Keep configuration separate from logic
56+
57+
## Shell Script Best Practices
58+
59+
- Use `set -e` to exit on errors
60+
- Quote variables: `"$VAR"` not `$VAR`
61+
- Use `[[` for conditionals (bash)
62+
- Prefer `local` variables in functions
63+
- Use meaningful return codes
64+
- Avoid global state when possible
65+
66+
## Testing Guidelines
67+
68+
- All features should have corresponding tests in `.github/workflows/tests.yml`
69+
- Test both valid and invalid inputs
70+
- Test CLI arguments in all formats: `--key value`, `--key=value`, `-k value`
71+
- Use dry-run mode for input validation tests
72+
- Use minimal sizes/runtimes for actual benchmark tests
73+
74+
## Docker Best Practices
75+
76+
- Keep the container minimal (scratch-based)
77+
- Only include necessary binaries
78+
- Use multi-stage builds
79+
- Set appropriate defaults via ENV
80+
- Run as non-root user (65534:65534)
81+
82+
## Output Formats
83+
84+
The tool supports multiple output formats:
85+
- Human-readable (default): colored, with emojis
86+
- JSON: structured, machine-readable
87+
- YAML: structured, human-friendly
88+
- XML: structured, enterprise-compatible
89+
90+
When modifying output, ensure all formats are updated consistently.

.github/workflows/docker-image.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,17 @@ jobs:
6666
id: version
6767
run: |
6868
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
69-
echo "version=${{ github.ref_name }}" >> $GITHUB_OUTPUT
69+
VERSION="${{ github.ref_name }}"
70+
VERSION="${VERSION#v}"
7071
else
71-
echo "version=${{ github.sha }}" >> $GITHUB_OUTPUT
72+
GIT_DESC=$(git describe --tags --always 2>/dev/null)
73+
if [[ "$GIT_DESC" =~ ^v?([0-9]+\.[0-9]+\.[0-9]+)-([0-9]+)-g([a-f0-9]+)$ ]]; then
74+
VERSION="${BASH_REMATCH[1]}-dev.${BASH_REMATCH[2]}+${BASH_REMATCH[3]}"
75+
else
76+
VERSION="0.0.0-dev+${GITHUB_SHA::7}"
77+
fi
7278
fi
79+
echo "version=$VERSION" >> $GITHUB_OUTPUT
7380
- name: Build and push Docker image
7481
uses: docker/build-push-action@v5
7582
with:

.github/workflows/security.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: Security Scan
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
schedule:
11+
- cron: "0 6 * * 1"
12+
workflow_dispatch:
13+
14+
permissions:
15+
contents: read
16+
security-events: write
17+
18+
jobs:
19+
trivy:
20+
name: Trivy
21+
runs-on: ubuntu-latest
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v4
25+
26+
- name: Build image
27+
run: docker build -t diskmark:scan .
28+
29+
- name: Run Trivy vulnerability scanner
30+
uses: aquasecurity/trivy-action@master
31+
with:
32+
image-ref: diskmark:scan
33+
format: sarif
34+
output: trivy-results.sarif
35+
severity: CRITICAL,HIGH,MEDIUM
36+
37+
- name: Upload Trivy scan results
38+
uses: github/codeql-action/upload-sarif@v3
39+
if: always()
40+
with:
41+
sarif_file: trivy-results.sarif
42+
43+
grype:
44+
name: Grype
45+
runs-on: ubuntu-latest
46+
steps:
47+
- name: Checkout
48+
uses: actions/checkout@v4
49+
50+
- name: Build image
51+
run: docker build -t diskmark:scan .
52+
53+
- name: Run Grype vulnerability scanner
54+
uses: anchore/scan-action@v6
55+
id: scan
56+
with:
57+
image: diskmark:scan
58+
fail-build: false
59+
severity-cutoff: medium
60+
61+
- name: Upload Grype scan results
62+
uses: github/codeql-action/upload-sarif@v3
63+
if: always()
64+
with:
65+
sarif_file: ${{ steps.scan.outputs.sarif }}

0 commit comments

Comments
 (0)