ci: switch to Earthly

Squashed commit of the following:

commit 06baa23fc8
Author: Tomáš Mládek <t@mldk.cz>
Date:   Wed Aug 23 11:10:19 2023 +0200

    ci, fix: forgot push

commit 6494be49d2
Author: Tomáš Mládek <t@mldk.cz>
Date:   Wed Aug 23 11:01:14 2023 +0200

    fix, ci: docker tag arg

commit 38682ba930
Author: Tomáš Mládek <t@mldk.cz>
Date:   Wed Aug 23 10:54:45 2023 +0200

    ci: parallelize push steps

commit 5eeab18aa0
Author: Tomáš Mládek <t@mldk.cz>
Date:   Wed Aug 23 10:52:37 2023 +0200

    ci, fix: docker login

commit ce10d0d04a
Author: Tomáš Mládek <t@mldk.cz>
Date:   Wed Aug 23 10:41:52 2023 +0200

    ci: remove earthly verbose

commit ff9b842968
Author: Tomáš Mládek <t@mldk.cz>
Date:   Wed Aug 23 10:41:23 2023 +0200

    ci, fix: typo

commit df80ee0610
Author: Tomáš Mládek <t@mldk.cz>
Date:   Wed Aug 23 10:06:47 2023 +0200

    ci, refactor: better step names

commit 80093f8964
Author: Tomáš Mládek <t@mldk.cz>
Date:   Wed Aug 23 10:05:03 2023 +0200

    ci, fix: earthly config for publish:appimage step

commit 650824df99
Author: Tomáš Mládek <t@mldk.cz>
Date:   Wed Aug 23 10:04:50 2023 +0200

    ci, refactor: only explicitly copy AppImages in sign target

commit 3b53e2dc64
Author: Tomáš Mládek <t@mldk.cz>
Date:   Wed Aug 23 08:01:43 2023 +0200

    ci: EARTHLY_VERBOSE=1

commit cec95ea29a
Author: Tomáš Mládek <t@mldk.cz>
Date:   Wed Aug 23 07:10:09 2023 +0200

    ci: earthly bootstrap after conf

commit 7afe653d57
Author: Tomáš Mládek <t@mldk.cz>
Date:   Wed Aug 23 07:04:08 2023 +0200

    ci, fix: remove ssh_key secret

commit b549d891ed
Author: Tomáš Mládek <t@mldk.cz>
Date:   Tue Aug 22 22:02:01 2023 +0200

    ci, fix: missing gpg-agent

commit 47938c7147
Author: Tomáš Mládek <t@mldk.cz>
Date:   Tue Aug 22 20:55:15 2023 +0200

    ci, fix: unify earthly config

commit 7b89ea7ef4
Author: Tomáš Mládek <t@mldk.cz>
Date:   Tue Aug 22 19:59:37 2023 +0200

    ci: publishing docker, appimage, nightlies

commit f4f94d9864
Author: Tomáš Mládek <t@mldk.cz>
Date:   Tue Aug 22 18:19:00 2023 +0200

    ci: add lint & test step

commit be180ed59b
Author: Tomáš Mládek <t@mldk.cz>
Date:   Mon Aug 21 16:13:03 2023 +0200

    ci, wip: earthly integration

commit 39db638cbd
Author: Tomáš Mládek <t@mldk.cz>
Date:   Mon Aug 21 16:12:21 2023 +0200

    ci: use `upend --version` for AppImage, move get_version.sh logic to cli

commit 5188336c7e
Author: Tomáš Mládek <t@mldk.cz>
Date:   Mon Aug 21 12:30:47 2023 +0200

    ci: refix AppImage, switch to appimage-builder, build docker

commit 27f7941020
Author: Tomáš Mládek <t@mldk.cz>
Date:   Sat Aug 19 18:55:03 2023 +0200

    wip: remote woodpecker CI config for the time being

commit 53e775b85d
Author: Tomáš Mládek <t@mldk.cz>
Date:   Sat Aug 19 18:47:59 2023 +0200

    wip: delete .env

    it's interpreted by Earthly and I'm not sure it's necessary anyway

commit 26bec32803
Author: Tomáš Mládek <t@mldk.cz>
Date:   Sat Aug 19 18:47:32 2023 +0200

    wip: initial somewhat functional Earthfile
feat/type-attributes
Tomáš Mládek 2023-08-23 12:13:24 +02:00
parent cae0154167
commit 42ab70fd07
10 changed files with 344 additions and 194 deletions

1
.env
View File

@ -1 +0,0 @@
DATABASE_URL=upend.sqlite3

2
.gitignore vendored
View File

@ -1,6 +1,4 @@
/dist
/*.AppImage
/*.asc
/target
**/*.rs.bk

View File

@ -1,169 +1,45 @@
pipeline:
cache:get:
image: meltwater/drone-cache:v1
pull: true
settings:
restore: true
endpoint:
from_secret: S3_ENDPOINT
access-key:
from_secret: S3_ACCESS_KEY
secret-key:
from_secret: S3_SECRET_KEY
bucket: "upend-ci-cache"
cache_key: "{{ .Commit.Branch }}"
path-style: true
region: anabasis
mount:
- ".cargo"
- "target"
- ".pnpm"
secrets: [S3_ENDPOINT, S3_ACCESS_KEY, S3_SECRET_KEY]
when:
event: push
prepare:cache:frontend:
group: init
image: albedo.lan:5000/upend-node:latest
pull: true
lint:
image: earthly/earthly:v0.7.15
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- FORCE_COLOR=1
- EARTHLY_EXEC_CMD="/bin/sh"
secrets: [EARTHLY_CONFIGURATION]
commands:
- pnpm config --location project set store-dir $CI_WORKSPACE/.pnpm
- mkdir -p $CI_WORKSPACE/.pnpm
- mkdir ~/.earthly && echo "$EARTHLY_CONFIGURATION" > ~/.earthly/config.yaml
- earthly bootstrap
- earthly +lint
prepare:cache:backend:
group: init
image: albedo.lan:5000/upend-rust:latest
pull: true
test:
image: earthly/earthly:v0.7.15
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- FORCE_COLOR=1
- EARTHLY_EXEC_CMD="/bin/sh"
secrets: [EARTHLY_CONFIGURATION]
commands:
- export CARGO_HOME=$CI_WORKSPACE/.cargo
- test -d $CARGO_HOME || cp -vr /usr/local/cargo $CARGO_HOME
- mkdir ~/.earthly && echo "$EARTHLY_CONFIGURATION" > ~/.earthly/config.yaml
- earthly bootstrap
- earthly +test
prepare:build:wasmlib:
image: albedo.lan:5000/upend-rust:latest
pull: true
appimage:
image: earthly/earthly:v0.7.15
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- FORCE_COLOR=1
- EARTHLY_EXEC_CMD="/bin/sh"
secrets: [EARTHLY_CONFIGURATION, REGISTRY, REGISTRY_USER, REGISTRY_PASSWORD]
commands:
- export CARGO_HOME=$CI_WORKSPACE/.cargo
- rustc --version && cargo --version
- task build:wasmlib
# volumes:
# - rust_registry:/usr/local/cargo
- mkdir ~/.earthly && echo "$EARTHLY_CONFIGURATION" > ~/.earthly/config.yaml
- earthly bootstrap
- earthly +appimage
build:backend:
group: build
image: albedo.lan:5000/upend-rust:latest
pull: true
commands:
- export CARGO_HOME=$CI_WORKSPACE/.cargo
- rustc --version && cargo --version
- task build:backend
# volumes:
# - rust_registry:/usr/local/cargo
build:frontend:
group: build
image: albedo.lan:5000/upend-node:latest
pull: true
commands:
- node --version && npm --version
- task build:frontend
lint:backend:
group: lint
image: albedo.lan:5000/upend-rust:latest
pull: true
commands:
- export CARGO_HOME=$CI_WORKSPACE/.cargo
- rustup component add clippy
- task lint:backend
- git status -vvv
# volumes:
# - rust_registry:/usr/local/cargo
when:
path:
- migrations/**/*
- /**/*.rs
- /**/Cargo.lock
- Taskfile.yml
lint:frontend:
group: lint
image: albedo.lan:5000/upend-node:latest
pull: true
commands:
- node --version && npm --version
- task lint:frontend
when:
path:
- webui/**/*
- Taskfile.yml
lint:jslib:
group: lint
image: albedo.lan:5000/upend-node:latest
pull: true
commands:
- node --version && npm --version
- task lint:jslib
when:
path:
- tools/upend_js/**/*
- Taskfile.yml
lint:webext:
group: lint
image: albedo.lan:5000/upend-node:latest
pull: true
commands:
- node --version && npm --version
- task lint:webext
when:
path:
- webext/**/*
- Taskfile.yml
test:backend:
group: test
image: albedo.lan:5000/upend-rust:latest
pull: true
commands:
- export CARGO_HOME=$CI_WORKSPACE/.cargo
- task test:backend
# volumes:
# - rust_registry:/usr/local/cargo
cache:push:
image: meltwater/drone-cache:v1
pull: true
settings:
rebuild: true
endpoint:
from_secret: S3_ENDPOINT
access-key:
from_secret: S3_ACCESS_KEY
secret-key:
from_secret: S3_SECRET_KEY
bucket: "upend-ci-cache"
cache_key: "{{ .Commit.Branch }}"
path-style: true
region: anabasis
mount:
- ".cargo"
- "target"
- ".pnpm"
secrets: [S3_ENDPOINT, S3_ACCESS_KEY, S3_SECRET_KEY]
when:
event: push
package:
image: albedo.lan:5000/upend-package:latest
pull: true
commands:
- git status -vvv
- task package
when:
event: [push, tag]
package:push:
appimage:save:
group: push
image: woodpeckerci/plugin-s3
settings:
endpoint:
@ -175,29 +51,66 @@ pipeline:
bucket: upend-ci-packages
path_style: true
region: anabasis
source: "*.AppImage"
source: "dist/*.AppImage"
target: /packages
secrets: [S3_ENDPOINT, S3_ACCESS_KEY, S3_SECRET_KEY]
publish:nightly:
image: albedo.lan:5000/upend-deploy:latest
pull: true
appimage:publish:nightly:
group: push
image: earthly/earthly:v0.7.15
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- FORCE_COLOR=1
- EARTHLY_EXEC_CMD="/bin/sh"
secrets:
[
EARTHLY_CONFIGURATION,
GPG_SIGN_KEY,
SSH_CONFIG,
SSH_UPLOAD_KEY,
SSH_KNOWN_HOSTS,
]
commands:
- echo "$GPG_SIGN_KEY" | gpg --import
- mkdir -p $HOME/.ssh
- echo "$SSH_CONFIG" > $HOME/.ssh/config
- echo "$SSH_UPLOAD_KEY" > $HOME/.ssh/id_rsa
- echo "$SSH_KNOWN_HOSTS" > $HOME/.ssh/known_hosts
- chmod 600 $HOME/.ssh/*
- gpg --clear-sign *.AppImage
- scp -v *.AppImage *.asc mainsite:releases/nightly
secrets: [gpg_sign_key, ssh_config, ssh_upload_key, ssh_known_hosts]
when:
event: push
branch: main
- mkdir ~/.earthly && echo "$EARTHLY_CONFIGURATION" > ~/.earthly/config.yaml
- earthly bootstrap
- earthly --secret GPG_SIGN_KEY --secret SSH_CONFIG --secret SSH_UPLOAD_KEY --secret SSH_KNOWN_HOSTS +deploy-appimage-nightly
publish:release:
docker:nightly:
group: push
image: earthly/earthly:v0.7.15
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- FORCE_COLOR=1
- EARTHLY_EXEC_CMD="/bin/sh"
secrets: [EARTHLY_CONFIGURATION, DOCKER_USER, DOCKER_PASSWORD]
commands:
- echo $${DOCKER_PASSWORD}| docker login --username $${DOCKER_USER} --password-stdin
- mkdir ~/.earthly && echo "$EARTHLY_CONFIGURATION" > ~/.earthly/config.yaml
- earthly bootstrap
- earthly --push +docker
docker:release:
group: push
image: earthly/earthly:v0.7.15
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- FORCE_COLOR=1
- EARTHLY_EXEC_CMD="/bin/sh"
secrets: [EARTHLY_CONFIGURATION, DOCKER_USER, DOCKER_PASSWORD]
commands:
- echo $${DOCKER_PASSWORD}| docker login --username $${DOCKER_USER} --password-stdin
- mkdir ~/.earthly && echo "$EARTHLY_CONFIGURATION" > ~/.earthly/config.yaml
- earthly bootstrap
- earthly --push +docker --tag=latest
- earthly --push +docker --tag=$CI_COMMIT_TAG
when:
event: [tag]
gitea:release:
group: push
image: woodpeckerci/plugin-gitea-release
settings:
base_url: https://git.thm.place

65
Cargo.lock generated
View File

@ -659,6 +659,7 @@ dependencies = [
"anstyle",
"bitflags 1.3.2",
"clap_lex",
"once_cell",
"strsim",
]
@ -702,6 +703,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "const_fn"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935"
[[package]]
name = "const_format"
version = "0.2.30"
@ -1258,6 +1265,19 @@ dependencies = [
"weezl",
]
[[package]]
name = "git2"
version = "0.17.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b989d6a7ca95a362cf2cfc5ad688b3a467be1f87e480b8dad07fee8c79b0044"
dependencies = [
"bitflags 1.3.2",
"libc",
"libgit2-sys",
"log",
"url",
]
[[package]]
name = "h2"
version = "0.3.18"
@ -1648,6 +1668,18 @@ version = "0.2.144"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
[[package]]
name = "libgit2-sys"
version = "0.15.2+1.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a80df2e11fb4a61f4ba2ab42dbe7f74468da143f1a75c74e11dee7c813f694fa"
dependencies = [
"cc",
"libc",
"libz-sys",
"pkg-config",
]
[[package]]
name = "libsqlite3-sys"
version = "0.22.2"
@ -1668,6 +1700,18 @@ dependencies = [
"cc",
]
[[package]]
name = "libz-sys"
version = "1.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "link-cplusplus"
version = "1.0.8"
@ -2741,8 +2785,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "970538704756fd0bb4ec8cb89f80674afb661e7c0fe716f9ba5be57717742300"
dependencies = [
"const_format",
"git2",
"is_debug",
"time 0.3.20",
"tzdb",
]
[[package]]
@ -3170,6 +3216,25 @@ version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "tz-rs"
version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33851b15c848fad2cf4b105c6bb66eb9512b6f6c44a4b13f57c53c73c707e2b4"
dependencies = [
"const_fn",
]
[[package]]
name = "tzdb"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec758958f2fb5069cd7fae385be95cc8eceb8cdfd270c7d14de6034f0108d99e"
dependencies = [
"iana-time-zone",
"tz-rs",
]
[[package]]
name = "unicase"
version = "2.6.0"

138
Earthfile Normal file
View File

@ -0,0 +1,138 @@
VERSION 0.7
appimage:
FROM --platform=linux/amd64 +base-rust
RUN apt-get update && \
apt-get -y install wget pipx binutils coreutils desktop-file-utils fakeroot fuse libgdk-pixbuf2.0-dev patchelf python3-pip python3-setuptools squashfs-tools strace util-linux zsync && \
pipx ensurepath && \
pipx install appimage-builder
COPY +upend-cli/bin AppDir/usr/bin/upend
COPY --dir +webui/dist AppDir/usr/share/upend/webui
COPY assets/upend.png AppDir/usr/share/icons/upend.png
COPY build/AppImageBuilder.yml .
RUN sed -e "s/latest/$(./AppDir/usr/bin/upend --version | cut -d ' ' -f 2)/" -i AppImageBuilder.yml
RUN pipx run appimage-builder
SAVE ARTIFACT UpEnd* AS LOCAL dist/
docker:
FROM debian:bookworm
RUN apt-get update && \
apt-get -y install libssl3 ffmpeg wget && \
wget https://github.com/bbc/audiowaveform/releases/download/1.8.1/audiowaveform_1.8.1-1-12_amd64.deb && \
apt -y install ./audiowaveform_1.8.1-1-12_amd64.deb && \
rm -v audiowaveform_1.8.1-1-12_amd64.deb && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
COPY +upend-cli/bin /usr/bin/upend
COPY --dir +webui/dist /usr/share/upend/webui
CMD ["/usr/bin/upend"]
ARG tag=trunk
SAVE IMAGE --push upend/upend:$tag
upend-cli:
FROM +base-rust
RUN cargo fetch
RUN cargo build --release
SAVE ARTIFACT target/release/upend-cli bin
webui:
FROM +base-node
COPY +jslib/jslib tools/upend_js
COPY +wasmlib/pkg tools/upend_wasm/pkg
WORKDIR webui
RUN pnpm install --frozen-lockfile
RUN pnpm build
SAVE ARTIFACT dist
wasmlib:
FROM --platform=linux/amd64 +base-rust
RUN cargo install wasm-pack wasm-bindgen-cli && rustup target add wasm32-unknown-unknown
WORKDIR tools/upend_wasm
RUN cargo fetch
RUN wasm-pack build --target web
SAVE ARTIFACT pkg
jslib:
FROM +base-node
COPY +wasmlib/pkg /upend/tools/upend_wasm/pkg
WORKDIR tools/upend_js
RUN pnpm install --frozen-lockfile
RUN pnpm build
SAVE ARTIFACT . jslib
webext:
FROM +base-node
WORKDIR webext
RUN pnpm install --frozen-lockfile
RUN pnpm build
lint:
WAIT
BUILD +lint-backend
BUILD +lint-frontend
BUILD +lint-jslib
END
lint-backend:
FROM +base-rust
RUN rustup component add clippy
RUN cargo fetch
RUN cargo clippy --workspace
lint-frontend:
FROM +base-node
COPY +wasmlib/pkg tools/upend_wasm/pkg
WORKDIR webui
RUN pnpm install --frozen-lockfile
RUN pnpm check && pnpm lint
lint-jslib:
FROM +base-node
COPY +wasmlib/pkg tools/upend_wasm/pkg
WORKDIR tools/upend_js
RUN pnpm install --frozen-lockfile
RUN pnpm lint
test:
WAIT
BUILD +test-backend
END
test-backend:
FROM +base-rust
RUN curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C /usr/local/cargo/bin
RUN cargo fetch
RUN cargo nextest run --workspace
appimage-signed:
FROM alpine
RUN apk add gpg gpg-agent
RUN --secret GPG_SIGN_KEY echo "$GPG_SIGN_KEY" | gpg --import
COPY +appimage/*.AppImage .
RUN gpg --clear-sign *.AppImage
SAVE ARTIFACT *.asc
deploy-appimage-nightly:
FROM +appimage-signed
RUN apk add openssh-client
RUN --secret SSH_CONFIG --secret SSH_UPLOAD_KEY --secret SSH_KNOWN_HOSTS \
mkdir -p $HOME/.ssh && \
echo "$SSH_CONFIG" > $HOME/.ssh/config && \
echo "$SSH_UPLOAD_KEY" > $HOME/.ssh/id_rsa && \
echo "$SSH_KNOWN_HOSTS" > $HOME/.ssh/known_hosts && \
chmod 600 $HOME/.ssh/*
RUN scp -v *.AppImage *.asc mainsite:releases/nightly
base-rust:
FROM rust:bookworm
WORKDIR /upend
COPY --dir base cli db Cargo.toml Cargo.lock .
COPY --dir tools/upend_wasm tools/upend_wasm
base-node:
FROM node:lts
RUN npm install -g pnpm
WORKDIR /upend
COPY --dir webui webext .
COPY --dir tools/upend_js tools/upend_js

38
build/AppImageBuilder.yml Normal file
View File

@ -0,0 +1,38 @@
# appimage-builder recipe see https://appimage-builder.readthedocs.io for details
version: 1
AppDir:
path: AppDir
app_info:
id: upend
name: UpEnd
icon: upend
version: latest
exec: usr/bin/upend
exec_args: $@
apt:
arch:
- amd64
allow_unauthenticated: true
sources:
- sourceline: deb http://deb.debian.org/debian/ bookworm main non-free-firmware
- sourceline: deb http://security.debian.org/debian-security bookworm-security
main non-free-firmware
- sourceline: deb http://deb.debian.org/debian/ bookworm-updates main non-free-firmware
stable
include:
- libssl3
- libc6:amd64
- locales
files:
include:
- lib64/ld-linux-x86-64.so.2
exclude:
- usr/share/man
- usr/share/doc/*/README.*
- usr/share/doc/*/changelog.*
- usr/share/doc/*/NEWS.*
- usr/share/doc/*/TODO.*
AppImage:
arch: x86_64
update-information: guess

View File

@ -1,9 +0,0 @@
#!/bin/sh
git_tag=$(git describe --tags --exact-match HEAD 2>/dev/null)
if [ -z "$git_tag" ]; then
echo "dev_$(git rev-parse --short HEAD)"
else
echo "$git_tag" | sed -e 's/^v//g'
fi

View File

@ -7,7 +7,7 @@ edition = "2021"
[dependencies]
upend-base = { path = "../base" }
upend-db = { path = "../db" }
clap = { version = "4.2.4", features = ["derive", "env", "color"] }
clap = { version = "4.2.4", features = ["derive", "env", "color", "string", "cargo"] }
log = "0.4"
tracing = "0.1"
@ -87,7 +87,7 @@ bytes = "1.4.0"
signal-hook = "0.3.15"
[build-dependencies]
shadow-rs = { version = "0.23", default-features = false }
shadow-rs = { version = "0.23" }
[features]
default = [

View File

@ -1,3 +1,4 @@
fn main() -> shadow_rs::SdResult<()> {
println!("cargo:rustc-env=GIT_TAG={}", shadow_rs::tag());
shadow_rs::new()
}

View File

@ -5,7 +5,7 @@ use crate::common::{get_static_dir, REQWEST_ASYNC_CLIENT};
use crate::config::UpEndConfig;
use actix_web::HttpServer;
use anyhow::Result;
use clap::{Args, Parser, Subcommand, ValueEnum};
use clap::{Args, CommandFactory, FromArgMatches, Parser, Subcommand, ValueEnum};
use filebuffer::FileBuffer;
use rand::{thread_rng, Rng};
use regex::Captures;
@ -40,7 +40,7 @@ mod extractors;
mod previews;
#[derive(Debug, Parser)]
#[command(name = "upend", author, version)]
#[command(name = "upend", author)]
struct Cli {
#[command(subcommand)]
command: Commands,
@ -179,7 +179,14 @@ struct ServeArgs {
#[actix_web::main]
async fn main() -> Result<()> {
let args = Cli::parse();
let upend_version = if env!("GIT_TAG").is_empty() {
format!("dev-{}", common::build::SHORT_COMMIT)
} else {
env!("GIT_TAG")[1..].to_string() // Remove the leading 'v'
};
let command = Cli::command().version(upend_version);
let args = Cli::from_arg_matches(&command.get_matches())?;
tracing_subscriber::fmt()
.with_env_filter(