Skip to content

Commit 68274e2

Browse files
committed
feat: add browser utility for opening URLs
feat: implement configuration management with AppConfig struct feat: add time utility for formatting timestamps test: add unit tests for cache functionality test: add unit tests for configuration loading test: add unit tests for GraphQL models serialization test: add unit tests for application state management test: add unit tests for time utility functions
0 parents  commit 68274e2

35 files changed

Lines changed: 7284 additions & 0 deletions

.github/workflows/ci.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [master, main]
6+
pull_request:
7+
branches: [master, main]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
RUSTFLAGS: -Dwarnings
12+
13+
jobs:
14+
fmt:
15+
name: Rustfmt
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v4
19+
- uses: dtolnay/rust-toolchain@stable
20+
with:
21+
components: rustfmt
22+
- run: cargo fmt --all -- --check
23+
24+
clippy:
25+
name: Clippy
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v4
29+
- uses: dtolnay/rust-toolchain@stable
30+
with:
31+
components: clippy
32+
- uses: Swatinem/rust-cache@v2
33+
- run: cargo clippy --all-targets --all-features
34+
35+
test:
36+
name: Tests
37+
runs-on: ubuntu-latest
38+
steps:
39+
- uses: actions/checkout@v4
40+
- uses: dtolnay/rust-toolchain@stable
41+
- uses: Swatinem/rust-cache@v2
42+
- run: cargo test --all-targets
43+
44+
build:
45+
name: Build
46+
runs-on: ubuntu-latest
47+
steps:
48+
- uses: actions/checkout@v4
49+
- uses: dtolnay/rust-toolchain@stable
50+
- uses: Swatinem/rust-cache@v2
51+
- run: cargo build --release

.github/workflows/release.yml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
permissions:
9+
contents: write
10+
11+
env:
12+
CARGO_TERM_COLOR: always
13+
14+
jobs:
15+
build:
16+
name: Build ${{ matrix.target }}
17+
runs-on: ${{ matrix.os }}
18+
strategy:
19+
fail-fast: false
20+
matrix:
21+
include:
22+
- target: x86_64-apple-darwin
23+
os: macos-latest
24+
archive: tar.gz
25+
- target: aarch64-apple-darwin
26+
os: macos-latest
27+
archive: tar.gz
28+
- target: x86_64-unknown-linux-gnu
29+
os: ubuntu-latest
30+
archive: tar.gz
31+
- target: aarch64-unknown-linux-gnu
32+
os: ubuntu-latest
33+
archive: tar.gz
34+
- target: x86_64-pc-windows-msvc
35+
os: windows-latest
36+
archive: zip
37+
38+
steps:
39+
- uses: actions/checkout@v4
40+
41+
- uses: dtolnay/rust-toolchain@stable
42+
with:
43+
targets: ${{ matrix.target }}
44+
45+
- uses: Swatinem/rust-cache@v2
46+
with:
47+
key: ${{ matrix.target }}
48+
49+
- name: Install cross-compilation tools
50+
if: matrix.target == 'aarch64-unknown-linux-gnu'
51+
run: |
52+
sudo apt-get update
53+
sudo apt-get install -y gcc-aarch64-linux-gnu
54+
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
55+
56+
- name: Build
57+
run: cargo build --release --target ${{ matrix.target }}
58+
59+
- name: Package (unix)
60+
if: matrix.archive == 'tar.gz'
61+
run: |
62+
cd target/${{ matrix.target }}/release
63+
tar czf ../../../ghdash-${{ matrix.target }}.tar.gz ghdash
64+
cd ../../..
65+
66+
- name: Package (windows)
67+
if: matrix.archive == 'zip'
68+
shell: pwsh
69+
run: |
70+
Compress-Archive -Path "target/${{ matrix.target }}/release/ghdash.exe" -DestinationPath "ghdash-${{ matrix.target }}.zip"
71+
72+
- name: Upload artifact
73+
uses: actions/upload-artifact@v4
74+
with:
75+
name: ghdash-${{ matrix.target }}
76+
path: ghdash-${{ matrix.target }}.${{ matrix.archive }}
77+
78+
release:
79+
name: Create Release
80+
needs: build
81+
runs-on: ubuntu-latest
82+
steps:
83+
- uses: actions/checkout@v4
84+
85+
- name: Download all artifacts
86+
uses: actions/download-artifact@v4
87+
with:
88+
path: artifacts
89+
merge-multiple: true
90+
91+
- name: Create GitHub Release
92+
uses: softprops/action-gh-release@v2
93+
with:
94+
generate_release_notes: true
95+
files: artifacts/*

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target

CONTRIBUTING.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Contributing to ghdash
2+
3+
Thank you for your interest in contributing to ghdash! This document provides guidelines to help you get started.
4+
5+
## Getting Started
6+
7+
1. Fork the repository and clone your fork:
8+
9+
```sh
10+
git clone https://github.com/your-username/ghdash.git
11+
cd ghdash
12+
```
13+
14+
2. Make sure you have Rust installed (1.85+ required for edition 2024):
15+
16+
```sh
17+
rustup update stable
18+
```
19+
20+
3. Build and run the tests:
21+
22+
```sh
23+
cargo build
24+
cargo test
25+
```
26+
27+
## Development Workflow
28+
29+
### Running locally
30+
31+
```sh
32+
# Create a config file
33+
mkdir -p ~/.config/ghdash
34+
cat > ~/.config/ghdash/config.toml << 'EOF'
35+
[github]
36+
users = ["your-github-username"]
37+
EOF
38+
39+
# Run in debug mode
40+
cargo run -- --debug
41+
```
42+
43+
### Code quality checks
44+
45+
Before submitting a PR, make sure all checks pass:
46+
47+
```sh
48+
cargo fmt --all -- --check # Formatting
49+
cargo clippy --all-targets # Linting
50+
cargo test --all-targets # Tests
51+
cargo build --release # Release build
52+
```
53+
54+
CI runs these same checks on every pull request.
55+
56+
### Project structure
57+
58+
```
59+
src/
60+
app/ App state machine, actions, reducer, event loop, layout
61+
github/ GraphQL client, queries, models, auth
62+
cache/ Disk cache with TTL
63+
ui/ Theme constants, widget rendering functions
64+
util/ Config loader, time formatting, browser helper
65+
tests/ Integration tests
66+
```
67+
68+
### Key design decisions
69+
70+
- **Action Channel pattern** — All events (keyboard, API responses) flow through a single `mpsc` channel as `Action`s. The `update()` function is a pure state reducer that returns `SideEffect`s, keeping state transitions testable.
71+
- **Bounded concurrency** — A `tokio::sync::Semaphore(4)` limits concurrent GitHub API requests.
72+
- **Client-side search** — Search filters the already-fetched PR list by substring matching. No additional API calls.
73+
- **Flat nav tree** — The navigation tree is a `Vec<NavNode>` rebuilt from org data whenever it changes, rather than a recursive tree structure.
74+
75+
## Making Changes
76+
77+
1. Create a branch for your change:
78+
79+
```sh
80+
git checkout -b my-feature
81+
```
82+
83+
2. Make your changes. Follow the existing code style — `cargo fmt` and `cargo clippy` enforce this.
84+
85+
3. Add tests for new functionality. Tests live in `tests/` as integration tests. The main test suites are:
86+
- `config_tests.rs` — Config parsing and defaults
87+
- `cache_tests.rs` — Cache set/get/TTL/invalidation
88+
- `state_tests.rs` — State transitions and the update reducer
89+
- `time_tests.rs` — Relative time formatting
90+
- `graphql_parse_tests.rs` — Model serialization and accessors
91+
92+
4. Run the full check suite:
93+
94+
```sh
95+
cargo fmt --all -- --check
96+
cargo clippy --all-targets
97+
cargo test --all-targets
98+
```
99+
100+
5. Commit and push your branch, then open a pull request.
101+
102+
## Pull Request Guidelines
103+
104+
- Keep PRs focused — one feature or fix per PR.
105+
- Write a clear description of what changed and why.
106+
- Ensure CI passes before requesting review.
107+
- Add tests for bug fixes and new features.
108+
109+
## Reporting Issues
110+
111+
- Use [GitHub Issues](https://github.com/zombocoder/ghdash/issues) to report bugs or request features.
112+
- Include your OS, Rust version (`rustc --version`), and steps to reproduce.
113+
114+
## License
115+
116+
By contributing to ghdash, you agree that your contributions will be licensed under the Apache License 2.0.

0 commit comments

Comments
 (0)