|
1 | | -# GitHub Actions Workflows |
| 1 | +# GitHub Workflows |
2 | 2 |
|
3 | | -## CI Workflow |
| 3 | +This directory contains GitHub Actions workflows for the hash-zig project. |
4 | 4 |
|
5 | | -The `ci.yml` workflow runs on every push or pull request to `main`, `master`, or `develop` branches. |
| 5 | +## Workflows |
6 | 6 |
|
7 | | -### Jobs |
| 7 | +### 1. CI (`ci.yml`) |
| 8 | +Runs on every push and pull request to main branches: |
| 9 | +- **Lint**: Checks code style and formatting |
| 10 | +- **Test**: Runs unit tests on Ubuntu, macOS, and Windows |
| 11 | +- **Build Examples**: Ensures all examples compile correctly |
8 | 12 |
|
9 | | -#### 1. Lint |
10 | | -- **Runs on:** Ubuntu Latest |
11 | | -- **Zig Version:** 0.14.1 |
12 | | -- **Steps:** |
13 | | - - Checkout code |
14 | | - - Setup Zig |
15 | | - - Run `zig build lint` (using zlinter) |
| 13 | +### 2. Performance Benchmark (`performance-benchmark.yml`) |
| 14 | +Runs on pull requests and can be triggered manually: |
| 15 | +- **Benchmarks current PR** against the base version |
| 16 | +- **Measures key generation, signing, and verification performance** |
| 17 | +- **Reports performance improvements** in PR comments |
| 18 | +- **Tests multiple lifetimes** (2^10 and 2^16 signatures) |
16 | 19 |
|
17 | | -#### 2. Test |
18 | | -- **Runs on:** Ubuntu, macOS, Windows |
19 | | -- **Zig Version:** 0.14.1 |
20 | | -- **Matrix Strategy:** Tests on 3 platforms |
21 | | -- **Steps:** |
22 | | - - Checkout code |
23 | | - - Setup Zig |
24 | | - - Run `zig build test` |
25 | | - - Build library with `zig build` |
| 20 | +## Performance Benchmarking |
26 | 21 |
|
27 | | -#### 3. Build Examples |
28 | | -- **Runs on:** Ubuntu Latest |
29 | | -- **Zig Version:** 0.14.1 |
30 | | -- **Dependencies:** Runs after lint and test jobs succeed |
31 | | -- **Steps:** |
32 | | - - Build library |
33 | | - - Run example application |
| 22 | +### What it measures |
| 23 | +- **Key Generation Time**: Time to generate keypairs for different lifetimes |
| 24 | +- **Sign Time**: Time to sign a message |
| 25 | +- **Verify Time**: Time to verify a signature |
| 26 | +- **Memory Usage**: Implicitly through execution time |
34 | 27 |
|
35 | | -### Trigger Events |
| 28 | +### How it works |
| 29 | +1. **Checkout current PR** and run benchmarks |
| 30 | +2. **Checkout base version** (previous commit) and run same benchmarks |
| 31 | +3. **Compare results** and calculate percentage improvements |
| 32 | +4. **Report results** in GitHub PR summary and console output |
36 | 33 |
|
37 | | -The workflow triggers on: |
38 | | -- **Push** to main, master, or develop branches |
39 | | -- **Pull requests** targeting main, master, or develop branches |
| 34 | +### Benchmark Results Format |
| 35 | +The benchmark outputs results in a structured format: |
| 36 | +``` |
| 37 | +BENCHMARK_RESULT: 2^10:keygen:1.234567 |
| 38 | +BENCHMARK_RESULT: 2^10:sign:0.000123 |
| 39 | +BENCHMARK_RESULT: 2^10:verify:0.000456 |
| 40 | +``` |
40 | 41 |
|
41 | | -### Badge |
| 42 | +### Running Benchmarks Locally |
42 | 43 |
|
43 | | -The CI status badge in README.md: |
| 44 | +#### Quick Benchmark |
| 45 | +```bash |
| 46 | +zig build benchmark |
| 47 | +``` |
44 | 48 |
|
45 | | -```markdown |
46 | | -[](https://github.com/ch4r10t33r/hash-zig/actions/workflows/ci.yml) |
| 49 | +#### Detailed Benchmark with Optimizations |
| 50 | +```bash |
| 51 | +zig build benchmark -Doptimize=ReleaseFast |
47 | 52 | ``` |
48 | 53 |
|
49 | | -### Local Testing |
| 54 | +#### Custom Benchmark Script |
| 55 | +```bash |
| 56 | +zig build-exe scripts/benchmark.zig -OReleaseFast --dep hash-zig -Mhash-zig=src/root.zig |
| 57 | +./benchmark |
| 58 | +``` |
50 | 59 |
|
51 | | -Before pushing, you can run the same checks locally with Zig 0.14.1: |
| 60 | +### Understanding Results |
52 | 61 |
|
53 | | -```bash |
54 | | -# Run linting |
55 | | -zig build lint |
| 62 | +#### Key Generation |
| 63 | +- **2^10 (1,024 signatures)**: Should complete in ~30-60 seconds |
| 64 | +- **2^16 (65,536 signatures)**: Should complete in ~5-15 minutes |
| 65 | +- **Improvement**: Positive percentage means faster generation |
56 | 66 |
|
57 | | -# Run tests |
58 | | -zig build test |
| 67 | +#### Sign/Verify |
| 68 | +- **Sign**: Should complete in ~100-500ms |
| 69 | +- **Verify**: Should complete in ~50-200ms |
| 70 | +- **Improvement**: Positive percentage means faster operations |
59 | 71 |
|
60 | | -# Build library |
61 | | -zig build |
| 72 | +### Performance Targets |
62 | 73 |
|
63 | | -# Run example |
64 | | -zig build example |
65 | | -``` |
| 74 | +Based on the optimization work, we expect: |
| 75 | +- **2-3x improvement** in key generation time |
| 76 | +- **10-30% improvement** in sign/verify operations |
| 77 | +- **Reduced memory allocations** (measured indirectly through speed) |
| 78 | + |
| 79 | +### Troubleshooting |
| 80 | + |
| 81 | +#### Benchmark Fails |
| 82 | +1. Check that the code compiles: `zig build -Doptimize=ReleaseFast` |
| 83 | +2. Verify tests pass: `zig build test` |
| 84 | +3. Check for memory issues on large lifetimes |
| 85 | + |
| 86 | +#### Inconsistent Results |
| 87 | +1. Run multiple times to get average |
| 88 | +2. Ensure system is not under heavy load |
| 89 | +3. Use ReleaseFast optimization mode |
| 90 | + |
| 91 | +#### CI Workflow Issues |
| 92 | +1. Check that the base commit exists |
| 93 | +2. Verify Zig version compatibility |
| 94 | +3. Check artifact upload permissions |
| 95 | + |
| 96 | +### Adding New Benchmarks |
| 97 | + |
| 98 | +To add new performance tests: |
| 99 | + |
| 100 | +1. **Add to benchmark script** (`scripts/benchmark.zig`): |
| 101 | + ```zig |
| 102 | + // New benchmark |
| 103 | + const new_start = std.time.nanoTimestamp(); |
| 104 | + // ... perform operation ... |
| 105 | + const new_end = std.time.nanoTimestamp(); |
| 106 | + const new_duration = @as(f64, @floatFromInt(new_end - new_start)) / 1_000_000_000.0; |
| 107 | + std.debug.print("BENCHMARK_RESULT: new_metric:{d:.6}\n", .{new_duration}); |
| 108 | + ``` |
66 | 109 |
|
67 | | -### Supported Zig Version |
| 110 | +2. **Update workflow** to capture new metrics: |
| 111 | + ```yaml |
| 112 | + NEW_METRIC=$(grep "BENCHMARK_RESULT: new_metric:" results.txt | cut -d: -f2) |
| 113 | + echo "new_metric=$NEW_METRIC" >> $GITHUB_OUTPUT |
| 114 | + ``` |
68 | 115 |
|
69 | | -- **0.14.1** - Required version (zlinter only supports 0.14.x) |
| 116 | +3. **Add to performance analysis**: |
| 117 | + ```yaml |
| 118 | + echo "| New Metric | ${{ steps.base.outputs.new_metric }}s | ${{ steps.current.outputs.new_metric }}s | ${improvement}% |" >> $GITHUB_STEP_SUMMARY |
| 119 | + ``` |
70 | 120 |
|
71 | | -**Note:** The project uses zlinter which currently only supports Zig 0.14.x. Once zlinter adds support for Zig 0.15+, the CI will be updated. |
| 121 | +## Workflow Triggers |
72 | 122 |
|
73 | | -### Platform Support |
| 123 | +### Automatic Triggers |
| 124 | +- **Push to main/master/develop**: Runs CI |
| 125 | +- **Pull Request to main/master/develop**: Runs CI + Performance Benchmark |
74 | 126 |
|
75 | | -- **Linux** (Ubuntu Latest) |
76 | | -- **macOS** (macOS Latest) |
77 | | -- **Windows** (Windows Latest) |
| 127 | +### Manual Triggers |
| 128 | +- **Workflow Dispatch**: Can manually trigger performance benchmark |
| 129 | +- **API Triggers**: Can be triggered via GitHub API |
78 | 130 |
|
79 | | -All tests must pass on all platforms before merging to protected branches. |
| 131 | +## Dependencies |
80 | 132 |
|
81 | | -### Linter (zlinter) |
| 133 | +### Required Tools |
| 134 | +- **Zig 0.14.1**: For compilation and testing |
| 135 | +- **bc**: For percentage calculations (available in Ubuntu runners) |
| 136 | +- **git**: For checking out different versions |
82 | 137 |
|
83 | | -The project uses [zlinter](https://github.com/kurtwagner/zlinter) - an extendable Zig linter integrated into the build system. |
| 138 | +### Optional Tools |
| 139 | +- **perf**: For detailed performance analysis (if needed) |
| 140 | +- **valgrind**: For memory profiling (if needed) |
84 | 141 |
|
85 | | -**Enabled rules:** |
86 | | -- `field_naming` - Enforce field naming conventions |
87 | | -- `declaration_naming` - Enforce declaration naming conventions (snake_case) |
88 | | -- `function_naming` - Enforce function naming conventions |
89 | | -- `no_unused` - Detect unused declarations |
90 | | -- `no_deprecated` - Warn about deprecated API usage |
| 142 | +## Best Practices |
91 | 143 |
|
92 | | -**Customization:** |
93 | | -See `build.zig` to add/remove rules or adjust severity levels. |
| 144 | +1. **Always use ReleaseFast** for performance benchmarks |
| 145 | +2. **Run multiple iterations** for stable results |
| 146 | +3. **Document performance targets** in PR descriptions |
| 147 | +4. **Include performance context** in commit messages |
| 148 | +5. **Monitor trends** over time to catch regressions |
0 commit comments