From 76cfc906ef0c75e551e2995810a521c5fa503ef5 Mon Sep 17 00:00:00 2001 From: Daniel Szabo Date: Mon, 7 Nov 2022 22:02:19 +0200 Subject: [PATCH 1/6] Update docker.yml Fix out of memory error on GH Actions build and automate GitHub Release with artifacts ( #47). See https://github.com/docker/build-push-action/issues/654#issuecomment-1285190151 and https://github.com/docker/build-push-action/issues/621 --- .github/workflows/docker.yml | 7 +- .github/workflows/gh-release.yml | 154 +++++++++++++++++++++++++++++++ Dockerfile | 1 + 3 files changed, 156 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/gh-release.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 5051c6b..2b99782 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -2,13 +2,8 @@ name: Docker Image on: push: - branches: - - "master" tags: - - "v*" - pull_request: - branches: - - "master" + - v[0-9]+.[0-9]+.[0-9]+* jobs: docker_image: diff --git a/.github/workflows/gh-release.yml b/.github/workflows/gh-release.yml new file mode 100644 index 0000000..66c88c8 --- /dev/null +++ b/.github/workflows/gh-release.yml @@ -0,0 +1,154 @@ +name: GitHub Release + +on: + push: + tags: + - v[0-9]+.[0-9]+.[0-9]+* + +jobs: + release: + name: Publish to Github Releases + outputs: + rc: ${{ steps.check-tag.outputs.rc }} + strategy: + matrix: + include: + - target: aarch64-unknown-linux-musl + os: ubuntu-latest + use-cross: true + cargo-flags: "" + - target: aarch64-apple-darwin + os: macos-latest + use-cross: true + cargo-flags: "" + - target: aarch64-pc-windows-msvc + os: windows-latest + use-cross: true + cargo-flags: "--no-default-features" + - target: x86_64-apple-darwin + os: macos-latest + cargo-flags: "" + - target: x86_64-pc-windows-msvc + os: windows-latest + cargo-flags: "" + - target: x86_64-unknown-linux-musl + os: ubuntu-latest + use-cross: true + cargo-flags: "" + - target: i686-unknown-linux-musl + os: ubuntu-latest + use-cross: true + cargo-flags: "" + - target: i686-pc-windows-msvc + os: windows-latest + use-cross: true + cargo-flags: "" + - target: armv7-unknown-linux-musleabihf + os: ubuntu-latest + use-cross: true + cargo-flags: "" + - target: arm-unknown-linux-musleabihf + os: ubuntu-latest + use-cross: true + cargo-flags: "" + - target: mips-unknown-linux-musl + os: ubuntu-latest + use-cross: true + cargo-flags: "--no-default-features" + - target: mipsel-unknown-linux-musl + os: ubuntu-latest + use-cross: true + cargo-flags: "--no-default-features" + - target: mips64-unknown-linux-gnuabi64 + os: ubuntu-latest + use-cross: true + cargo-flags: "--no-default-features" + - target: mips64el-unknown-linux-gnuabi64 + os: ubuntu-latest + use-cross: true + cargo-flags: "--no-default-features" + runs-on: ${{matrix.os}} + + steps: + - uses: actions/checkout@v2 + + - name: Check Tag + id: check-tag + shell: bash + run: | + tag=${GITHUB_REF##*/} + echo "::set-output name=version::$tag" + if [[ "$tag" =~ [0-9]+.[0-9]+.[0-9]+$ ]]; then + echo "::set-output name=rc::false" + else + echo "::set-output name=rc::true" + fi + + + - name: Install Rust Toolchain Components + uses: actions-rs/toolchain@v1 + with: + override: true + target: ${{ matrix.target }} + toolchain: stable + profile: minimal # minimal component installation (ie, no documentation) + + - name: Show Version Information (Rust, cargo, GCC) + shell: bash + run: | + gcc --version || true + rustup -V + rustup toolchain list + rustup default + cargo -V + rustc -V + + - name: Build + uses: actions-rs/cargo@v1 + with: + use-cross: ${{ matrix.use-cross }} + command: build + args: --locked --release --target=${{ matrix.target }} ${{ matrix.cargo-flags }} + + - name: Build Archive + shell: bash + id: package + env: + target: ${{ matrix.target }} + version: ${{ steps.check-tag.outputs.version }} + run: | + set -euxo pipefail + + bin=${GITHUB_REPOSITORY##*/} + src=`pwd` + dist=$src/dist + name=$bin-$version-$target + executable=target/$target/release/$bin + + if [[ "$RUNNER_OS" == "Windows" ]]; then + executable=$executable.exe + fi + + mkdir $dist + cp $executable $dist + cd $dist + + if [[ "$RUNNER_OS" == "Windows" ]]; then + archive=$dist/$name.zip + 7z a $archive * + echo "::set-output name=archive::`pwd -W`/$name.zip" + else + archive=$dist/$name.tar.gz + tar czf $archive * + echo "::set-output name=archive::$archive" + fi + + - name: Publish Archive + uses: softprops/action-gh-release@v0.1.5 + if: ${{ startsWith(github.ref, 'refs/tags/') }} + with: + draft: false + files: ${{ steps.package.outputs.archive }} + prerelease: ${{ steps.check-tag.outputs.rc == 'true' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 3e10f7a..eca64cb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,7 @@ RUN \ DEBIAN_FRONTEND=noninteractive \ apt-get update &&\ apt-get -y install ca-certificates tzdata &&\ + CARGO_NET_GIT_FETCH_WITH_CLI=true \ cargo build --release # https://hub.docker.com/r/bitnami/minideb From f41c2eb66b303ce1991d1220f00ad9a8b3a0ee28 Mon Sep 17 00:00:00 2001 From: figsoda Date: Tue, 8 Nov 2022 16:22:42 -0500 Subject: [PATCH 2/6] rename README.MD to README.md --- README.MD => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README.MD => README.md (100%) diff --git a/README.MD b/README.md similarity index 100% rename from README.MD rename to README.md From 958466818b416dbdafeaeac6c25393d13b74f9fc Mon Sep 17 00:00:00 2001 From: figsoda Date: Tue, 8 Nov 2022 16:30:16 -0500 Subject: [PATCH 3/6] apply clippy suggestions --- src/endpoints/create.rs | 4 ++-- src/endpoints/edit.rs | 21 +++++++++------------ src/endpoints/info.rs | 2 +- src/endpoints/pasta.rs | 20 ++++++++++---------- src/endpoints/qr.rs | 4 ++-- src/endpoints/remove.rs | 4 ++-- src/endpoints/static_resources.rs | 2 +- src/pasta.rs | 6 +++--- src/util/animalnumbers.rs | 8 ++++---- src/util/dbio.rs | 2 +- src/util/hashids.rs | 2 +- src/util/syntaxhighlighter.rs | 4 ++-- 12 files changed, 38 insertions(+), 41 deletions(-) diff --git a/src/endpoints/create.rs b/src/endpoints/create.rs index 715007e..d2cb5c3 100644 --- a/src/endpoints/create.rs +++ b/src/endpoints/create.rs @@ -122,7 +122,7 @@ pub async fn create( while let Some(chunk) = field.try_next().await? { content.push_str(std::str::from_utf8(&chunk).unwrap().to_string().as_str()); } - if content.len() > 0 { + if !content.is_empty() { new_pasta.content = content; new_pasta.pasta_type = if is_valid_url(new_pasta.content.as_str()) { @@ -152,7 +152,7 @@ pub async fn create( None => continue, }; - let mut file = match PastaFile::from_unsanitized(&path) { + let mut file = match PastaFile::from_unsanitized(path) { Ok(f) => f, Err(e) => { warn!("Unsafe file name: {e:?}"); diff --git a/src/endpoints/edit.rs b/src/endpoints/edit.rs index b361aec..53d2707 100644 --- a/src/endpoints/edit.rs +++ b/src/endpoints/edit.rs @@ -22,9 +22,9 @@ pub async fn get_edit(data: web::Data, id: web::Path) -> HttpR let mut pastas = data.pastas.lock().unwrap(); let id = if ARGS.hash_ids { - hashid_to_u64(&*id).unwrap_or(0) + hashid_to_u64(&id).unwrap_or(0) } else { - to_u64(&*id.into_inner()).unwrap_or(0) + to_u64(&id.into_inner()).unwrap_or(0) }; remove_expired(&mut pastas); @@ -38,7 +38,7 @@ pub async fn get_edit(data: web::Data, id: web::Path) -> HttpR } return HttpResponse::Ok().content_type("text/html").body( EditTemplate { - pasta: &pasta, + pasta, args: &ARGS, } .render() @@ -65,9 +65,9 @@ pub async fn post_edit( } let id = if ARGS.hash_ids { - hashid_to_u64(&*id).unwrap_or(0) + hashid_to_u64(&id).unwrap_or(0) } else { - to_u64(&*id.into_inner()).unwrap_or(0) + to_u64(&id.into_inner()).unwrap_or(0) }; let mut pastas = data.pastas.lock().unwrap(); @@ -77,20 +77,17 @@ pub async fn post_edit( let mut new_content = String::from(""); while let Some(mut field) = payload.try_next().await? { - match field.name() { - "content" => { - while let Some(chunk) = field.try_next().await? { - new_content = std::str::from_utf8(&chunk).unwrap().to_string(); - } + if field.name() == "content" { + while let Some(chunk) = field.try_next().await? { + new_content = std::str::from_utf8(&chunk).unwrap().to_string(); } - _ => {} } } for (i, pasta) in pastas.iter().enumerate() { if pasta.id == id { if pasta.editable { - pastas[i].content.replace_range(.., &*new_content); + pastas[i].content.replace_range(.., &new_content); save_to_file(&pastas); return Ok(HttpResponse::Found() diff --git a/src/endpoints/info.rs b/src/endpoints/info.rs index b2d8cd2..775a04a 100644 --- a/src/endpoints/info.rs +++ b/src/endpoints/info.rs @@ -17,7 +17,7 @@ struct Info<'a> { #[get("/info")] pub async fn info(data: web::Data) -> HttpResponse { // get access to the pasta collection - let mut pastas = data.pastas.lock().unwrap(); + let pastas = data.pastas.lock().unwrap(); // todo status report more sophisticated let mut status = "OK"; diff --git a/src/endpoints/pasta.rs b/src/endpoints/pasta.rs index 208664c..cf31fa3 100644 --- a/src/endpoints/pasta.rs +++ b/src/endpoints/pasta.rs @@ -6,7 +6,7 @@ use crate::util::animalnumbers::to_u64; use crate::util::hashids::to_u64 as hashid_to_u64; use crate::util::misc::remove_expired; use crate::AppState; -use actix_web::rt::time; + use actix_web::{get, web, HttpResponse}; use askama::Template; use std::time::{SystemTime, UNIX_EPOCH}; @@ -24,9 +24,9 @@ pub async fn getpasta(data: web::Data, id: web::Path) -> HttpR let mut pastas = data.pastas.lock().unwrap(); let id = if ARGS.hash_ids { - hashid_to_u64(&*id).unwrap_or(0) + hashid_to_u64(&id).unwrap_or(0) } else { - to_u64(&*id.into_inner()).unwrap_or(0) + to_u64(&id.into_inner()).unwrap_or(0) }; // remove expired pastas (including this one if needed) @@ -45,7 +45,7 @@ pub async fn getpasta(data: web::Data, id: web::Path) -> HttpR if found { // increment read count - pastas[index].read_count = pastas[index].read_count + 1; + pastas[index].read_count += 1; // save the updated read count save_to_file(&pastas); @@ -88,9 +88,9 @@ pub async fn redirecturl(data: web::Data, id: web::Path) -> Ht let mut pastas = data.pastas.lock().unwrap(); let id = if ARGS.hash_ids { - hashid_to_u64(&*id).unwrap_or(0) + hashid_to_u64(&id).unwrap_or(0) } else { - to_u64(&*id.into_inner()).unwrap_or(0) + to_u64(&id.into_inner()).unwrap_or(0) }; // remove expired pastas (including this one if needed) @@ -110,7 +110,7 @@ pub async fn redirecturl(data: web::Data, id: web::Path) -> Ht if found { // increment read count - pastas[index].read_count = pastas[index].read_count + 1; + pastas[index].read_count += 1; // save the updated read count save_to_file(&pastas); @@ -155,9 +155,9 @@ pub async fn getrawpasta(data: web::Data, id: web::Path) -> St let mut pastas = data.pastas.lock().unwrap(); let id = if ARGS.hash_ids { - hashid_to_u64(&*id).unwrap_or(0) + hashid_to_u64(&id).unwrap_or(0) } else { - to_u64(&*id.into_inner()).unwrap_or(0) + to_u64(&id.into_inner()).unwrap_or(0) }; // remove expired pastas (including this one if needed) @@ -176,7 +176,7 @@ pub async fn getrawpasta(data: web::Data, id: web::Path) -> St if found { // increment read count - pastas[index].read_count = pastas[index].read_count + 1; + pastas[index].read_count += 1; // get current unix time in seconds let timenow: i64 = match SystemTime::now().duration_since(UNIX_EPOCH) { diff --git a/src/endpoints/qr.rs b/src/endpoints/qr.rs index ab4ea32..5d2c86d 100644 --- a/src/endpoints/qr.rs +++ b/src/endpoints/qr.rs @@ -7,8 +7,8 @@ use crate::util::misc::{self, remove_expired}; use crate::AppState; use actix_web::{get, web, HttpResponse}; use askama::Template; -use qrcode_generator::QrCodeEcc; -use std::time::{SystemTime, UNIX_EPOCH}; + + #[derive(Template)] #[template(path = "qr.html", escape = "none")] diff --git a/src/endpoints/remove.rs b/src/endpoints/remove.rs index 0378a00..9a26021 100644 --- a/src/endpoints/remove.rs +++ b/src/endpoints/remove.rs @@ -21,9 +21,9 @@ pub async fn remove(data: web::Data, id: web::Path) -> HttpRes let mut pastas = data.pastas.lock().unwrap(); let id = if ARGS.hash_ids { - hashid_to_u64(&*id).unwrap_or(0) + hashid_to_u64(&id).unwrap_or(0) } else { - to_u64(&*id.into_inner()).unwrap_or(0) + to_u64(&id.into_inner()).unwrap_or(0) }; for (i, pasta) in pastas.iter().enumerate() { diff --git a/src/endpoints/static_resources.rs b/src/endpoints/static_resources.rs index d314416..e82fc6e 100644 --- a/src/endpoints/static_resources.rs +++ b/src/endpoints/static_resources.rs @@ -1,4 +1,4 @@ -use actix_web::{web, App, HttpResponse, HttpServer, Responder}; +use actix_web::{web, HttpResponse, Responder}; use mime_guess::from_path; use rust_embed::RustEmbed; diff --git a/src/pasta.rs b/src/pasta.rs index f20ce7d..04ee45d 100644 --- a/src/pasta.rs +++ b/src/pasta.rs @@ -118,7 +118,7 @@ impl Pasta { }; // it's less than 1 second????? - return String::from("just now"); + String::from("just now") } pub fn last_read_days_ago(&self) -> u16 { @@ -132,7 +132,7 @@ impl Pasta { } as i64; // get seconds since last read and convert it to days - return ((timenow - self.last_read) / 86400) as u16; + ((timenow - self.last_read) / 86400) as u16 } pub fn content_syntax_highlighted(&self) -> String { @@ -144,7 +144,7 @@ impl Pasta { } pub fn content_escaped(&self) -> String { - self.content.replace("`", "\\`").replace("$", "\\$") + self.content.replace('`', "\\`").replace('$', "\\$") } } diff --git a/src/util/animalnumbers.rs b/src/util/animalnumbers.rs index 29e5094..eb003f1 100644 --- a/src/util/animalnumbers.rs +++ b/src/util/animalnumbers.rs @@ -24,7 +24,7 @@ pub fn to_animal_names(mut number: u64) -> String { number -= digit * ANIMAL_NAMES.len().pow(power) as u64; if power > 0 { power -= 1; - } else if power <= 0 || number == 0 { + } else if power == 0 || number == 0 { break; } } @@ -35,12 +35,12 @@ pub fn to_animal_names(mut number: u64) -> String { pub fn to_u64(animal_names: &str) -> Result { let mut result: u64 = 0; - let animals: Vec<&str> = animal_names.split("-").collect(); + let animals: Vec<&str> = animal_names.split('-').collect(); let mut pow = animals.len(); - for i in 0..animals.len() { + for animal in animals { pow -= 1; - let animal_index = ANIMAL_NAMES.iter().position(|&r| r == animals[i]); + let animal_index = ANIMAL_NAMES.iter().position(|&r| r == animal); match animal_index { None => return Err("Failed to convert animal name to u64!"), Some(_) => { diff --git a/src/util/dbio.rs b/src/util/dbio.rs index 12dff06..9bf573d 100644 --- a/src/util/dbio.rs +++ b/src/util/dbio.rs @@ -4,7 +4,7 @@ use std::io::{BufReader, BufWriter}; use crate::Pasta; -static DATABASE_PATH: &'static str = "pasta_data/database.json"; +static DATABASE_PATH: &str = "pasta_data/database.json"; pub fn save_to_file(pasta_data: &Vec) { let mut file = File::create(DATABASE_PATH); diff --git a/src/util/hashids.rs b/src/util/hashids.rs index e9cdb1f..0e53f31 100644 --- a/src/util/hashids.rs +++ b/src/util/hashids.rs @@ -13,6 +13,6 @@ pub fn to_u64(hash_id: &str) -> Result { let ids = HARSH .decode(hash_id) .map_err(|_e| "Failed to decode hash ID")?; - let id = ids.get(0).ok_or("No ID found in hash ID")?; + let id = ids.first().ok_or("No ID found in hash ID")?; Ok(*id) } diff --git a/src/util/syntaxhighlighter.rs b/src/util/syntaxhighlighter.rs index 4b3f2a2..58d2433 100644 --- a/src/util/syntaxhighlighter.rs +++ b/src/util/syntaxhighlighter.rs @@ -11,7 +11,7 @@ pub fn html_highlight(text: &str, extension: &str) -> String { let syntax = ps .find_syntax_by_extension(extension) - .or(Option::from(ps.find_syntax_plain_text())) + .or_else(|| Option::from(ps.find_syntax_plain_text())) .unwrap(); let mut h = HighlightLines::new(syntax, &ts.themes["InspiredGitHub"]); @@ -33,5 +33,5 @@ pub fn html_highlight(text: &str, extension: &str) -> String { highlighted_content2 = highlighted_content2.replace("style=\"color:#183691;\"", "style=\"color:blue;\""); - return highlighted_content2; + highlighted_content2 } From 89f902f99f2f84027455866ac4ced8ebb096dc00 Mon Sep 17 00:00:00 2001 From: Karol Winiarski Date: Wed, 9 Nov 2022 10:26:44 +0100 Subject: [PATCH 4/6] doc: fixed invalid link to main website Link to a resource outside the repo itself should be prepended with https. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 474dc03..1b61899 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ And run with your custom configuration: Or get the Docker image from [Dockerhub: danielszabo99/microbin](https://hub.docker.com/r/danielszabo99/microbin) -On our website [microbin.eu](microbin.eu) you will find the following: +On our website [microbin.eu](https://microbin.eu) you will find the following: - [Screenshots](https://microbin.eu/screenshots/) - [Quickstart Guide](https://microbin.eu/quickstart/) @@ -67,4 +67,4 @@ You can use MicroBin MicroBin and MicroBin.eu are available under the BSD 3-Clause License. -© Dániel Szabó 2022 \ No newline at end of file +© Dániel Szabó 2022 From 089bb95c4f1e0320d48b283836a913cd7d7f47a7 Mon Sep 17 00:00:00 2001 From: figsoda Date: Tue, 8 Nov 2022 16:37:49 -0500 Subject: [PATCH 5/6] cargo fmt --- src/endpoints/edit.rs | 11 +++-------- src/endpoints/qr.rs | 2 -- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/endpoints/edit.rs b/src/endpoints/edit.rs index 53d2707..1e0bfff 100644 --- a/src/endpoints/edit.rs +++ b/src/endpoints/edit.rs @@ -36,14 +36,9 @@ pub async fn get_edit(data: web::Data, id: web::Path) -> HttpR .append_header(("Location", format!("{}/", ARGS.public_path))) .finish(); } - return HttpResponse::Ok().content_type("text/html").body( - EditTemplate { - pasta, - args: &ARGS, - } - .render() - .unwrap(), - ); + return HttpResponse::Ok() + .content_type("text/html") + .body(EditTemplate { pasta, args: &ARGS }.render().unwrap()); } } diff --git a/src/endpoints/qr.rs b/src/endpoints/qr.rs index 5d2c86d..c89275e 100644 --- a/src/endpoints/qr.rs +++ b/src/endpoints/qr.rs @@ -8,8 +8,6 @@ use crate::AppState; use actix_web::{get, web, HttpResponse}; use askama::Template; - - #[derive(Template)] #[template(path = "qr.html", escape = "none")] struct QRTemplate<'a> { From 68f408174519450ac01f3dff6799e752743b44a3 Mon Sep 17 00:00:00 2001 From: figsoda Date: Wed, 9 Nov 2022 10:46:51 -0500 Subject: [PATCH 6/6] fix typos --- Dockerfile | 4 ++-- README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index eca64cb..33fc4a8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,7 +26,7 @@ COPY --from=build \ /etc/ssl/certs/ca-certificates.crt \ /etc/ssl/certs/ca-certificates.crt -# copy built exacutable +# copy built executable COPY --from=build \ /app/target/release/microbin \ /usr/bin/microbin @@ -34,4 +34,4 @@ COPY --from=build \ # Expose webport used for the webserver to the docker runtime EXPOSE 8080 -ENTRYPOINT ["microbin"] \ No newline at end of file +ENTRYPOINT ["microbin"] diff --git a/README.md b/README.md index 1b61899..e7b23c3 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ On our website [microbin.eu](https://microbin.eu) you will find the following: - [Screenshots](https://microbin.eu/screenshots/) - [Quickstart Guide](https://microbin.eu/quickstart/) - [Documentation](https://microbin.eu/documentation/) -- [Donations and Sponsorhip](https://microbin.eu/donate/) +- [Donations and Sponsorships](https://microbin.eu/donate/) - [Community](https://microbin.eu/community/) ### Features