From 1def2850b33e9978b43fc5e4e7e202aa4d4349b9 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Fri, 31 May 2024 01:16:15 +0200 Subject: [PATCH 1/3] ci: add Dockerfile and CI workflow --- .forgejo/workflows/ci.yaml | 66 +++++++++++++++ .gitignore | 1 + Cargo.lock | 167 +++++++++++++++++++++++++++---------- Cargo.toml | 22 ++++- Dockerfile | 10 +++ 5 files changed, 218 insertions(+), 48 deletions(-) create mode 100644 .forgejo/workflows/ci.yaml create mode 100644 Dockerfile diff --git a/.forgejo/workflows/ci.yaml b/.forgejo/workflows/ci.yaml new file mode 100644 index 0000000..d2cc0c8 --- /dev/null +++ b/.forgejo/workflows/ci.yaml @@ -0,0 +1,66 @@ +name: CI +on: + push: + pull_request: + +jobs: + test: + runs-on: cimaster-latest + steps: + - name: ๐Ÿ‘๏ธ Checkout repository + uses: actions/checkout@v4 + - name: ๐Ÿฆ€ Setup Rust cache + uses: https://github.com/Swatinem/rust-cache@v2 + - name: ๐Ÿ“Ž Clippy + run: cargo clippy --all -- -D warnings + - name: ๐Ÿงช Test + run: cargo test + + release: + runs-on: cimaster-latest + needs: test + if: ${{ startsWith(github.ref, 'refs/tags/v') }} + steps: + - name: ๐Ÿ‘๏ธ Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # important to fetch tag logs + + - name: โš’๏ธ Build application + run: | + PKG_CONFIG_SYSROOT_DIR=/usr/x86_64-linux-gnu cargo build --release --target x86_64-unknown-linux-gnu + PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu cargo build --release --target aarch64-unknown-linux-gnu + - name: ๐Ÿ‹ Build docker image + uses: https://code.thetadev.de/ThetaDev/action-kaniko@v1 + with: + image: thetadev256/artifactview + username: thetadev256 + password: ${{ secrets.DOCKER_TOKEN }} + tag: ${{ github.ref_name }} + tag_with_latest: ${{ startsWith(github.ref, 'refs/tags/v') }} + platforms: "linux/amd64,linux/arm64" + + - name: Prepare release + if: ${{ startsWith(github.ref, 'refs/tags/v') }} + run: | + mkdir dist + tar -cJf dist/artifactview-x86_64-${{ github.ref_name }}.tar.xz -C target/x86_64-unknown-linux-gnu/release artifactview + tar -cJf dist/artifactview-aarch64-${{ github.ref_name }}.tar.xz -C target/aarch64-unknown-linux-gnu/release artifactview + + { + echo 'CHANGELOG<> "$GITHUB_ENV" + + - name: ๐ŸŽ‰ Publish release + if: ${{ startsWith(github.ref, 'refs/tags/v') }} + uses: https://gitea.com/actions/release-action@main + with: + title: "artifactview ${{ github.ref_name }}" + body: "${{ env.CHANGELOG }}" + files: dist/* + + - name: ๐Ÿš€ Deploy to server + run: | + curl -s -H "Authorization: Bearer ${{ secrets.THETADEV_DE_WATCHTOWER_TOKEN }}" https://watchtower.thetadev.de/v1/update diff --git a/.gitignore b/.gitignore index 4f83806..aebe389 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target +/dist /.env diff --git a/Cargo.lock b/Cargo.lock index 3e413d6..323af5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -365,12 +365,6 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.5.0" @@ -596,15 +590,6 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" -[[package]] -name = "encoding_rs" -version = "0.8.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" -dependencies = [ - "cfg-if", -] - [[package]] name = "env_filter" version = "0.1.0" @@ -1010,6 +995,23 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + [[package]] name = "hyper-tls" version = "0.6.0" @@ -1331,7 +1333,7 @@ version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ - "bitflags 2.5.0", + "bitflags", "cfg-if", "foreign-types", "libc", @@ -1531,7 +1533,7 @@ checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.5.0", + "bitflags", "lazy_static", "num-traits", "rand", @@ -1630,7 +1632,7 @@ version = "11.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e29830cbb1290e404f24c73af91c5d8d631ce7e128691e9477556b540cd01ecd" dependencies = [ - "bitflags 2.5.0", + "bitflags", ] [[package]] @@ -1639,7 +1641,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" dependencies = [ - "bitflags 2.5.0", + "bitflags", ] [[package]] @@ -1685,14 +1687,13 @@ checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" dependencies = [ "base64 0.22.1", "bytes", - "encoding_rs", "futures-core", "futures-util", - "h2", "http", "http-body", "http-body-util", "hyper", + "hyper-rustls", "hyper-tls", "hyper-util", "ipnet", @@ -1703,14 +1704,17 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls", + "rustls-native-certs", "rustls-pemfile", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", - "system-configuration", "tokio", "tokio-native-tls", + "tokio-rustls", "tokio-util", "tower-service", "url", @@ -1718,9 +1722,25 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", + "webpki-roots", "winreg", ] +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rstest" version = "0.20.0" @@ -1770,13 +1790,40 @@ version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.5.0", + "bitflags", "errno", "libc", "linux-raw-sys", "windows-sys 0.52.0", ] +[[package]] +name = "rustls" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "2.1.2" @@ -1793,6 +1840,17 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" +[[package]] +name = "rustls-webpki" +version = "0.102.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.17" @@ -1838,7 +1896,7 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 2.5.0", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -2010,6 +2068,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "spinning_top" version = "0.3.0" @@ -2059,27 +2123,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tempfile" version = "3.10.1" @@ -2196,6 +2239,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.11" @@ -2258,7 +2312,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags 2.5.0", + "bitflags", "bytes", "http", "http-body", @@ -2399,6 +2453,12 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.0" @@ -2563,6 +2623,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2875,6 +2944,12 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + [[package]] name = "zip" version = "0.6.6" diff --git a/Cargo.toml b/Cargo.toml index ee93f72..c72831e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,8 +3,20 @@ name = "artifactview" version = "0.1.0" edition = "2021" +[features] +default = ["native-tls"] + +# Reqwest TLS options +native-tls = ["reqwest/native-tls"] +rustls-tls-webpki-roots = ["reqwest/rustls-tls-webpki-roots"] +rustls-tls-native-roots = ["reqwest/rustls-tls-native-roots"] + [dependencies] -async_zip = { path = "crates/async_zip", features = ["tokio", "tokio-fs", "deflate"] } +async_zip = { path = "crates/async_zip", features = [ + "tokio", + "tokio-fs", + "deflate", +] } axum = { version = "0.7.5", features = ["http2"] } axum-extra = { version = "0.9.3", features = ["typed-header"] } dotenvy = "0.15.7" @@ -25,7 +37,10 @@ pin-project = "1.1.5" quick_cache = "0.5.1" rand = "0.8.5" regex = "1.10.4" -reqwest = { version = "0.12.4", features = ["json", "stream"] } +reqwest = { version = "0.12.4", default-features = false, features = [ + "json", + "stream", +] } serde = { version = "1.0.203", features = ["derive"] } serde-env = "0.1.1" serde-hex = "0.1.0" @@ -49,3 +64,6 @@ rstest = { version = "0.20.0", default-features = false } [workspace] members = [".", "crates/*"] resolver = "2" + +[profile.release] +strip = true diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9fc13e0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +FROM debian:bookworm-slim + +ARG TARGETARCH_ALT + +RUN apt-get update && apt-get install -y libssl3 ca-certificates dumb-init && apt-get clean + +COPY target/${TARGETARCH_ALT}-unknown-linux-gnu/release/artifactview /usr/bin/artifactview + +EXPOSE 3000 +ENTRYPOINT ["dumb-init", "artifactview"] From a37e9c4fa242521c0cc2f28f29a3246a08d13b48 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Fri, 31 May 2024 01:30:38 +0200 Subject: [PATCH 2/3] chore: update Cargo.toml metadata --- Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index c72831e..495d81b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,10 @@ name = "artifactview" version = "0.1.0" edition = "2021" +authors = ["ThetaDev "] +license = "MIT" +repository = "https://codeberg.org/ThetaDev/artifactview" +description = "Browse GitHub/Gitea/Forgejo Actions artifacts" [features] default = ["native-tls"] From 9c8d60bec167ea55f1fc22bc41c853ecf4d285e1 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Fri, 31 May 2024 01:39:10 +0200 Subject: [PATCH 3/3] fix: show GitHub error message --- src/artifact_api.rs | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/artifact_api.rs b/src/artifact_api.rs index 47013e6..945ab06 100644 --- a/src/artifact_api.rs +++ b/src/artifact_api.rs @@ -5,7 +5,7 @@ use std::path::Path; use futures_lite::StreamExt; use http::header; use quick_cache::sync::Cache as QuickCache; -use reqwest::{Client, ClientBuilder, IntoUrl, RequestBuilder, Url}; +use reqwest::{Client, ClientBuilder, IntoUrl, RequestBuilder, Response, Url}; use serde::{Deserialize, Serialize}; use tokio::{fs::File, io::AsyncWriteExt}; @@ -51,6 +51,11 @@ struct ForgejoArtifact { status: ForgejoArtifactStatus, } +#[derive(Deserialize)] +struct ApiError { + message: String, +} + #[derive(Deserialize)] struct ArtifactsWrap { artifacts: Vec, @@ -226,11 +231,8 @@ impl ArtifactApi { query.user, query.repo, query.run ); - let resp = self - .get_github(url) - .send() + let resp = Self::handle_github_error(self.get_github(url).send().await?) .await? - .error_for_status()? .json::>() .await?; @@ -247,16 +249,26 @@ impl ArtifactApi { query.user, query.repo, query.artifact ); - let artifact = self - .get_github(url) - .send() + let artifact = Self::handle_github_error(self.get_github(url).send().await?) .await? - .error_for_status()? .json::() .await?; Ok(artifact.into_artifact(query)) } + async fn handle_github_error(resp: Response) -> Result { + if let Err(e) = resp.error_for_status_ref() { + let status = resp.status(); + let msg = resp.json::().await.ok(); + Err(Error::HttpClient( + msg.map(|msg| msg.message).unwrap_or(e.to_string()).into(), + status, + )) + } else { + Ok(resp) + } + } + fn get_github(&self, url: U) -> RequestBuilder { let mut builder = self.http.get(url);