From 1e36edf49978e8ba24a85d4663ff3ebaf9642a29 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sat, 22 Jun 2024 16:57:32 +0200 Subject: [PATCH 1/7] fix: PR comment emoji prefix detection --- Cargo.lock | 42 ------------------------------------------ Cargo.toml | 1 - src/app.rs | 16 +--------------- src/util.rs | 24 ++++++++++++++++++++++++ 4 files changed, 25 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c778b5d..a0bb6b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,7 +187,6 @@ dependencies = [ "tower-http", "tracing", "tracing-subscriber", - "unic-emoji-char", "url", "yarte", "yarte_helpers", @@ -3145,47 +3144,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" -[[package]] -name = "unic-char-property" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" -dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-emoji-char" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b07221e68897210270a38bde4babb655869637af0f69407f96053a34f76494d" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", -] - [[package]] name = "unicase" version = "2.7.0" diff --git a/Cargo.toml b/Cargo.toml index 480de16..b19413e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,7 +73,6 @@ tokio-util = { version = "0.7.11", features = ["io"] } tower-http = { version = "0.5.2", features = ["trace", "set-header"] } tracing = "0.1.40" tracing-subscriber = "0.3.18" -unic-emoji-char = "0.9.0" url = "2.5.0" yarte = { version = "0.15.7", features = ["json"] } diff --git a/src/app.rs b/src/app.rs index b34ae4e..ea76c4d 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,5 +1,4 @@ use std::{ - borrow::Cow, collections::{BTreeMap, HashMap}, fmt::Write, net::{IpAddr, SocketAddr}, @@ -866,20 +865,7 @@ fn pr_comment_text(p: PrCommentTextParams) -> String { }; let write_link_icon = |s: &mut String, title: &str, href: &str| { - // Move leading emoji into a prefix variable since including them in the link does not look good - let mut title_pfx = String::new(); - let mut title = Cow::Borrowed(title); - if let Some((i, c)) = title - .char_indices() - // Some emoji use variation selectors that are not included in is_emoji - .find(|(_, c)| !unic_emoji_char::is_emoji(*c) && !('\u{fe00}'..='\u{fe0f}').contains(c)) - { - if i > 0 && c == ' ' { - title[..i + 1].clone_into(&mut title_pfx); - title = title[i + 1..].to_owned().into(); - } - } - + let (title_pfx, title) = util::split_icon_prefix(title); _ = write!( s, r#"{title_pfx}{title}"#, diff --git a/src/util.rs b/src/util.rs index 4fa6dba..d5d43c0 100644 --- a/src/util.rs +++ b/src/util.rs @@ -302,6 +302,18 @@ pub fn extract_delim<'a>(s: &'a str, start: &str, end: &str) -> Option<&'a str> None } +pub fn split_icon_prefix(s: &str) -> (&str, &str) { + if let Some((i, c)) = s + .char_indices() + .find(|(_, c)| c.is_ascii() || c.is_alphanumeric()) + { + if i > 0 && c == ' ' && s.get(i + 1..).is_some() { + return (&s[..i + 1], &s[i + 1..]); + } + } + ("", s) +} + #[cfg(test)] pub(crate) mod tests { use std::path::{Path, PathBuf}; @@ -390,4 +402,16 @@ pub(crate) mod tests { let res = super::filename_ext(filename); assert_eq!(res, expect); } + + #[rstest] + #[case("๐Ÿงช Test", ("๐Ÿงช ", "Test"))] + #[case("๐Ÿงช๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ Test", ("๐Ÿงช๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ ", "Test"))] + #[case("๐Ÿงช ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ Test", ("๐Ÿงช ", "๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ Test"))] + #[case("", ("", ""))] + #[case("Test", ("", "Test"))] + #[case("้‹ๅ‘ฝ Test", ("", "้‹ๅ‘ฝ Test"))] + fn split_icon_prefix(#[case] s: &str, #[case] expect: (&str, &str)) { + let res = super::split_icon_prefix(s); + assert_eq!(res, expect); + } } From 09e7c1d8bdfe082a26cb4e6483072c0221c304d5 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sat, 22 Jun 2024 17:17:36 +0200 Subject: [PATCH 2/7] chore(release): release artifactview v0.4.2 --- CHANGELOG.md | 7 +++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4bfedf..f1c8c5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. +## [v0.4.2](https://codeberg.org/ThetaDev/artifactview/compare/v0.4.1..v0.4.2) - 2024-06-22 + +### ๐Ÿ› Bug Fixes + +- PR comment emoji prefix detection - ([1e36edf](https://codeberg.org/ThetaDev/artifactview/commit/1e36edf49978e8ba24a85d4663ff3ebaf9642a29)) + + ## [v0.4.1](https://codeberg.org/ThetaDev/artifactview/compare/v0.4.0..v0.4.1) - 2024-06-22 ### ๐Ÿš€ Features diff --git a/Cargo.lock b/Cargo.lock index a0bb6b0..4fe8603 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -141,7 +141,7 @@ dependencies = [ [[package]] name = "artifactview" -version = "0.4.1" +version = "0.4.2" dependencies = [ "async_zip", "axum", diff --git a/Cargo.toml b/Cargo.toml index b19413e..8490e04 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "artifactview" -version = "0.4.1" +version = "0.4.2" edition = "2021" authors = ["ThetaDev "] license = "MIT" From d8c3ab4f36727f118b31683db87d287d9945ee14 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sat, 22 Jun 2024 18:34:09 +0200 Subject: [PATCH 3/7] fix: 404 error on GitHub comment creation --- README.md | 19 +++++++++++++------ src/artifact_api.rs | 18 ++++++++++++------ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 1e7e6cc..c486622 100644 --- a/README.md +++ b/README.md @@ -76,13 +76,19 @@ artifacts. ![Pull request comment](./resources/screenshotPrComment.png) To accomplish that, simply add this step to your CI workflow (after uploading the -artifacts). +artifacts). Note that the workflow URL has to be built differently on GitHub and +Forgejo, so this solution is sadly not cross-forge compatible. ```yaml -- name: ๐Ÿ”— Artifactview PR comment +- name: ๐Ÿ”— Artifactview PR comment (Forgejo) if: ${{ always() && github.event_name == 'pull_request' }} run: | curl -SsL --fail-with-body -w "\n" -X POST https://av.thetadev.de/.well-known/api/prComment -H "Content-Type: application/json" --data "{\"url\": \"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_NUMBER\", \"pr\": ${{ github.event.number }}}" + +- name: ๐Ÿ”— Artifactview PR comment (GitHub) + if: ${{ always() && github.event_name == 'pull_request' }} + run: | + curl -SsL --fail-with-body -w "\n" -X POST https://av.thetadev.de/.well-known/api/prComment -H "Content-Type: application/json" --data "{\"url\": \"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID\", \"pr\": ${{ github.event.number }}}" ``` ## API @@ -254,11 +260,12 @@ Example list: `foo;bar`, example map: `foo=>f1;bar=>b1` ### Access tokens GitHub does not allow downloading artifacts for public repositories for unauthenticated -users. So you need to setup an access token to use Artifactview with GitHub. These are -the permissions that need to be enabled: +users. So you need to setup an access token to use Artifactview with GitHub. -- Repository access: All repositories -- Repository permissions: Pull requests (Read and write) +If you are not using the `prComment` feature, you can use a fine-grained access token +with the "Public repositories (read-only)" permission. If you want to create pull +request comments, you have to use a classic token with the "public_repo" scope enabled +(the fine-grained tokens did not work in my test). Forgejo does not require access tokens to download artifacts on public repositories, so you only need to create a token if you want to use the `prComment`-API. In this case, diff --git a/src/artifact_api.rs b/src/artifact_api.rs index 69c6068..e0edb52 100644 --- a/src/artifact_api.rs +++ b/src/artifact_api.rs @@ -269,6 +269,7 @@ impl ArtifactApi { } } + #[tracing::instrument(level = "error", skip_all)] pub async fn list(&self, query: &RunQuery, cached: bool) -> Result> { let cache_key = query.cache_key(); let fut = async { @@ -290,6 +291,7 @@ impl ArtifactApi { } } + #[tracing::instrument(level = "error", skip_all)] pub async fn fetch(&self, query: &ArtifactQuery) -> Result { if query.is_github() { self.fetch_github(query).await @@ -305,6 +307,7 @@ impl ArtifactApi { } } + #[tracing::instrument(level = "error", skip_all)] pub async fn download(&self, artifact: &Artifact, path: &Path) -> Result<()> { if artifact.expired { return Err(Error::Expired); @@ -416,10 +419,9 @@ impl ArtifactApi { 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, - )) + let msg_str = msg.map(|msg| msg.message).unwrap_or(e.to_string()).into(); + tracing::error!("API error: {msg_str}"); + Err(Error::HttpClient(msg_str, status)) } else { Ok(resp) } @@ -492,6 +494,7 @@ impl ArtifactApi { .header(header::AUTHORIZATION, format!("token {token}"))) } + #[tracing::instrument(level = "error", skip_all)] pub async fn workflow_run(&self, query: &RunQuery) -> Result { if query.is_github() { self.workflow_run_github(query).await @@ -554,6 +557,7 @@ impl ArtifactApi { Ok(run.into()) } + #[tracing::instrument(level = "error", skip_all)] pub async fn add_comment( &self, query: QueryRef<'_>, @@ -621,8 +625,8 @@ impl ArtifactApi { ) -> Result { if let Some(old_comment_id) = old_comment_id { let url = format!( - "https://api.github.com/repos/{}/{}/issues/{}/comments/{}", - query.user, query.repo, issue_id, old_comment_id + "https://api.github.com/repos/{}/{}/issues/comments/{}", + query.user, query.repo, old_comment_id ); if recreate { Self::send_api_req_empty(self.req_github(Method::DELETE, url)?).await?; @@ -650,6 +654,7 @@ impl ArtifactApi { Ok(new_c.id) } + #[tracing::instrument(level = "error", skip_all)] pub async fn find_comment( &self, query: QueryRef<'_>, @@ -702,6 +707,7 @@ impl ArtifactApi { Ok(None) } + #[tracing::instrument(level = "error", skip_all)] pub async fn get_pr(&self, query: QueryRef<'_>, pr_id: u64) -> Result { let req = if query.is_github() { self.get_github(format!( From bdc847f5d0bdde596b0b7ee31913d7fd4a474501 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sat, 22 Jun 2024 18:34:55 +0200 Subject: [PATCH 4/7] chore(release): release artifactview v0.4.3 --- CHANGELOG.md | 7 +++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1c8c5d..8ab8fad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. +## [v0.4.3](https://codeberg.org/ThetaDev/artifactview/compare/v0.4.2..v0.4.3) - 2024-06-22 + +### ๐Ÿ› Bug Fixes + +- 404 error on GitHub comment creation - ([d8c3ab4](https://codeberg.org/ThetaDev/artifactview/commit/d8c3ab4f36727f118b31683db87d287d9945ee14)) + + ## [v0.4.2](https://codeberg.org/ThetaDev/artifactview/compare/v0.4.1..v0.4.2) - 2024-06-22 ### ๐Ÿ› Bug Fixes diff --git a/Cargo.lock b/Cargo.lock index 4fe8603..c9226a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -141,7 +141,7 @@ dependencies = [ [[package]] name = "artifactview" -version = "0.4.2" +version = "0.4.3" dependencies = [ "async_zip", "axum", diff --git a/Cargo.toml b/Cargo.toml index 8490e04..4dc070c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "artifactview" -version = "0.4.2" +version = "0.4.3" edition = "2021" authors = ["ThetaDev "] license = "MIT" From 3690b0244cf47d0d73511f5f69f5d12abe0f1837 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sat, 22 Jun 2024 18:47:49 +0200 Subject: [PATCH 5/7] fix: use forge aliases for PR comment links --- src/app.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.rs b/src/app.rs index ea76c4d..cc05ad6 100644 --- a/src/app.rs +++ b/src/app.rs @@ -672,7 +672,7 @@ impl App { .extract::, _>() .await .map_err(|e| Error::BadRequest(e.body_text().into()))?; - let query = RunQuery::from_forge_url(&req.url)?; + let query = RunQuery::from_forge_url_alias(&req.url, &state.i.cfg.load().site_aliases)?; if let Some(limiter) = &state.i.lim_pr_comment { limiter.check_key(&ip).map_err(Error::from)?; From 0516abb8fddccaf02e261107cd68c39ce560b568 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sat, 22 Jun 2024 18:48:35 +0200 Subject: [PATCH 6/7] chore(release): release artifactview v0.4.4 --- CHANGELOG.md | 7 +++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ab8fad..2d77011 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. +## [v0.4.4](https://codeberg.org/ThetaDev/artifactview/compare/v0.4.3..v0.4.4) - 2024-06-22 + +### ๐Ÿ› Bug Fixes + +- Use forge aliases for PR comment links - ([3690b02](https://codeberg.org/ThetaDev/artifactview/commit/3690b0244cf47d0d73511f5f69f5d12abe0f1837)) + + ## [v0.4.3](https://codeberg.org/ThetaDev/artifactview/compare/v0.4.2..v0.4.3) - 2024-06-22 ### ๐Ÿ› Bug Fixes diff --git a/Cargo.lock b/Cargo.lock index c9226a6..6e0c455 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -141,7 +141,7 @@ dependencies = [ [[package]] name = "artifactview" -version = "0.4.3" +version = "0.4.4" dependencies = [ "async_zip", "axum", diff --git a/Cargo.toml b/Cargo.toml index 4dc070c..dc1a8fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "artifactview" -version = "0.4.3" +version = "0.4.4" edition = "2021" authors = ["ThetaDev "] license = "MIT" From 39f0019455cc23f1b8c39b77d2aaa5af278731a9 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sat, 22 Jun 2024 19:27:45 +0200 Subject: [PATCH 7/7] docs: make example CI step compatible with GitHub+Forgejo --- .forgejo/workflows/ci.yaml | 4 +++- README.md | 13 ++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/.forgejo/workflows/ci.yaml b/.forgejo/workflows/ci.yaml index e2e258e..0276410 100644 --- a/.forgejo/workflows/ci.yaml +++ b/.forgejo/workflows/ci.yaml @@ -32,4 +32,6 @@ jobs: run: | echo "Run: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_NUMBER" echo "Pull: ${{ github.event.number }}" - curl -SsL --fail-with-body -w "\n" -X POST https://av.thetadev.de/.well-known/api/prComment -H "Content-Type: application/json" --data "{\"url\": \"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_NUMBER\", \"pr\": ${{ github.event.number }}, \"artifact_titles\": {\"test\":\"๐Ÿงช Test report\"}, \"artifact_paths\": {\"test\":\"/junit.xml?viewer=1\"}}" + + if [[ "$GITEA_ACTIONS" == "true" ]]; then RUN_NUMBER="$GITHUB_RUN_NUMBER"; else RUN_NUMBER="$GITHUB_RUN_ID"; fi + curl -SsL --fail-with-body -w "\n" -X POST https://av.thetadev.de/.well-known/api/prComment -H "Content-Type: application/json" --data "{\"url\": \"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$RUN_NUMBER\", \"pr\": ${{ github.event.number }}, \"artifact_titles\": {\"test\":\"๐Ÿงช Test report\"}, \"artifact_paths\": {\"test\":\"/junit.xml?viewer=1\"}}" diff --git a/README.md b/README.md index c486622..92df5e0 100644 --- a/README.md +++ b/README.md @@ -76,19 +76,14 @@ artifacts. ![Pull request comment](./resources/screenshotPrComment.png) To accomplish that, simply add this step to your CI workflow (after uploading the -artifacts). Note that the workflow URL has to be built differently on GitHub and -Forgejo, so this solution is sadly not cross-forge compatible. +artifacts). ```yaml -- name: ๐Ÿ”— Artifactview PR comment (Forgejo) +- name: ๐Ÿ”— Artifactview PR comment if: ${{ always() && github.event_name == 'pull_request' }} run: | - curl -SsL --fail-with-body -w "\n" -X POST https://av.thetadev.de/.well-known/api/prComment -H "Content-Type: application/json" --data "{\"url\": \"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_NUMBER\", \"pr\": ${{ github.event.number }}}" - -- name: ๐Ÿ”— Artifactview PR comment (GitHub) - if: ${{ always() && github.event_name == 'pull_request' }} - run: | - curl -SsL --fail-with-body -w "\n" -X POST https://av.thetadev.de/.well-known/api/prComment -H "Content-Type: application/json" --data "{\"url\": \"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID\", \"pr\": ${{ github.event.number }}}" + if [[ "$GITEA_ACTIONS" == "true" ]]; then RUN_NUMBER="$GITHUB_RUN_NUMBER"; else RUN_NUMBER="$GITHUB_RUN_ID"; fi + curl -SsL --fail-with-body -w "\n" -X POST https://av.thetadev.de/.well-known/api/prComment -H "Content-Type: application/json" --data "{\"url\": \"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$RUN_NUMBER\", \"pr\": ${{ github.event.number }}}" ``` ## API