diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..d5770e5
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,32 @@
+name: CI
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ workflow_dispatch:
+
+env:
+ CARGO_TERM_COLOR: always
+
+jobs:
+ check:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: dtolnay/rust-toolchain@stable
+ with:
+ components: rustfmt, clippy
+ - uses: Swatinem/rust-cache@v2
+ - name: Format
+ run: cargo fmt --all --check
+ - name: Clippy
+ run: cargo clippy --all-targets --locked -- -D warnings
+ - name: Test
+ run: cargo test --locked
+ - name: Build
+ run: cargo build --release --locked
+ - uses: actions/upload-artifact@v4
+ with:
+ name: dfetch-x86_64-linux
+ path: target/release/dfetch
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..b2a0485
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,79 @@
+name: Release
+
+on:
+ push:
+ tags: ["v*"]
+
+env:
+ CARGO_TERM_COLOR: always
+
+permissions:
+ contents: write
+
+jobs:
+ build:
+ name: Build ${{ matrix.target }}
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - target: x86_64-unknown-linux-gnu
+ os: ubuntu-latest
+ - target: x86_64-unknown-linux-musl
+ os: ubuntu-latest
+ - target: aarch64-unknown-linux-gnu
+ os: ubuntu-24.04-arm
+ - target: aarch64-unknown-linux-musl
+ os: ubuntu-24.04-arm
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Check tag matches Cargo.toml version
+ run: |
+ version=$(grep -m1 '^version' Cargo.toml | cut -d'"' -f2)
+ if [ "v$version" != "$GITHUB_REF_NAME" ]; then
+ echo "::error::Tag $GITHUB_REF_NAME does not match Cargo.toml version v$version"
+ exit 1
+ fi
+
+ - name: Install musl tools
+ if: contains(matrix.target, 'musl')
+ run: sudo apt-get update && sudo apt-get install -y musl-tools
+
+ - uses: dtolnay/rust-toolchain@stable
+ with:
+ targets: ${{ matrix.target }}
+
+ - uses: Swatinem/rust-cache@v2
+ with:
+ key: ${{ matrix.target }}
+
+ - name: Build
+ run: cargo build --release --locked --target ${{ matrix.target }}
+
+ - name: Package
+ run: |
+ name=dfetch-${GITHUB_REF_NAME}-${{ matrix.target }}
+ mkdir "$name"
+ cp target/${{ matrix.target }}/release/dfetch README.md LICENSE "$name/"
+ tar czf "$name.tar.gz" "$name"
+ sha256sum "$name.tar.gz" > "$name.tar.gz.sha256"
+
+ - uses: actions/upload-artifact@v4
+ with:
+ name: ${{ matrix.target }}
+ path: dfetch-*.tar.gz*
+
+ release:
+ needs: build
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/download-artifact@v4
+ with:
+ path: dist
+ merge-multiple: true
+ - uses: softprops/action-gh-release@v2
+ with:
+ files: dist/*
+ generate_release_notes: true
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
deleted file mode 100644
index 315f9df..0000000
--- a/.github/workflows/rust.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: Rust
-
-on:
- push:
-
-env:
- CARGO_TERM_COLOR: always
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v3
- - name: Build
- run: cargo build --release
- - name: Upload a Build Artifact
- uses: actions/upload-artifact@v3.1.2
- with:
- path: ./target/release/dfetch
diff --git a/README.md b/README.md
index abc4a52..e2ca4b2 100644
--- a/README.md
+++ b/README.md
@@ -15,3 +15,21 @@ However, maintaining clean code is also a priority..
- emerge ( [Gentoo Linux](https://www.gentoo.org/) )
btw, i'll be happy if somebody send some cool ascii cat arts in issues :point_right::point_left:
+
+### installation
+
+Prebuilt static (musl) and glibc binaries for `x86_64` and `aarch64` are attached to every [release](https://github.com/DeityLamb/dfetch/releases).
+
+```sh
+cargo install --git https://github.com/DeityLamb/dfetch
+```
+
+### releasing
+
+Bump `version` in `Cargo.toml`, commit, then push a matching tag:
+
+```sh
+git tag v0.1.2 && git push origin v0.1.2
+```
+
+The `Release` workflow builds all targets and publishes a GitHub release with generated notes.
diff --git a/src/main.rs b/src/main.rs
index 1ffd712..f372060 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -19,7 +19,10 @@ fn main() {
じ しˍ,)ノ {memory_field: bool {
diff --git a/src/package_managers/xbps.rs b/src/package_managers/xbps.rs
index 7e4fc5b..94e1a4d 100644
--- a/src/package_managers/xbps.rs
+++ b/src/package_managers/xbps.rs
@@ -29,7 +29,7 @@ impl PackageManager for XBPSPackageManager {
Ok(io::BufReader::new(File::open(file.path())?)
.lines()
- .flatten()
+ .map_while(Result::ok)
.filter(|line| line.contains("repository"))
.count() as u64)
}