Skip to content

Commit

Permalink
#13: Add Standalone Version (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
dylhack committed Aug 23, 2023
1 parent 1f70a7b commit 2f3f15f
Show file tree
Hide file tree
Showing 10 changed files with 214 additions and 35 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/release_cowbot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ on:
types: [published]

env:
REGISTRY: ghcr.io
IMAGE_NAME: cowsay-bot
REGISTRY: ghcr.io/dylhack
IMAGE_NAME: cowbot

jobs:
publish:
Expand Down
60 changes: 60 additions & 0 deletions .github/workflows/release_cowbot_standalone.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Publish Cowbot (Standalone)

on:
release:
types: [published]

env:
REGISTRY: ghcr.io/dylhack
IMAGE_NAME: cowbot-standalone

jobs:
publish:
name: Publish Cowbot
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform:
- linux/amd64
- linux/arm/v7
- linux/arm64
permissions:
contents: read
packages: write
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
- name: Log in to the Container registry
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
target: cowbot-standalone-production
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: ${{ matrix.platform }}
6 changes: 3 additions & 3 deletions .github/workflows/release_cowserve.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
name: Publish Cowbot
name: Publish Cowserve

on:
release:
types: [published]

env:
REGISTRY: ghcr.io
IMAGE_NAME: cowsay-serve
REGISTRY: ghcr.io/dylhack
IMAGE_NAME: cowserve

jobs:
publish:
Expand Down
10 changes: 10 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ FROM base AS cowbot-builder
WORKDIR /opt/cowsay/cowbot
RUN cargo build --release

FROM base AS cowbot-standalone-builder

WORKDIR /opt/cowsay/cowbot
RUN cargo build --release --no-default-features

FROM base AS cowserve-builder

WORKDIR /opt/cowsay/cowserve
Expand All @@ -23,3 +28,8 @@ FROM base AS cowbot-production

COPY --from=cowbot-builder /opt/cowsay/cowbot/target/release/cowbot /usr/local/bin/cowbot
CMD cowbot

FROM base AS cowbot-standalone-production

COPY --from=cowbot-standalone-builder /opt/cowsay/cowbot/target/release/cowbot /usr/local/bin/cowbot
CMD cowbot
20 changes: 1 addition & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,5 @@
Docker is recommended for setup.

```sh
docker run -d -e BOT_TOKEN=token ghcr.io/dylhack/cowsay-bot:latest
```

## Without Docker

You can use this setup also for development. If you plan on developing make
sure to set the `DEV_SERVER_ID` in the `.env`.

**Requirements**

- [Rust](https://www.rust-lang.org/)
- [Proto Buffer](https://protobuf.dev/downloads/)

```sh
git clone https://github.com/dylhack/cowsay-bot
cd cowsay-bot
cp .env.example .env
# Make sure to set the BOT_TOKEN before running
cargo run
docker run -d -e BOT_TOKEN=token ghcr.io/dylhack/cowsay-bot-standalone:latest
```
4 changes: 4 additions & 0 deletions cowbot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ name = "cowbot"
version = "0.1.0"
edition = "2021"

[features]
cowserve = []
default = ["cowserve"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
ansi_colours = "1.2.2"
Expand Down
4 changes: 2 additions & 2 deletions cowbot/src/bot/events/ready.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use super::super::commands::register_all;
use serenity::{model::gateway::Ready, prelude::Context as SerenityContext};

pub async fn handle(ctx: &SerenityContext, _ready: &Ready) {
pub async fn handle(ctx: &SerenityContext, rdy: &Ready) {
if let Err(why) = register_all(ctx).await {
println!("Error registering commands: {}", why);
}

println!("Ready!")
println!("Ready as {}!", rdy.user.tag());
}
61 changes: 53 additions & 8 deletions cowbot/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
pub mod cowfiles {
tonic::include_proto!("cowfiles");
}
use self::cowfiles::{CowfileDescriptor, GetCowfileRequest};
use crate::{client::cowfiles::GetCowfilesRequest, config};
#[cfg(not(feature = "cowserve"))]
mod builtin;
#[cfg(feature = "cowserve")]
use crate::config;
use anyhow::{anyhow, Result};
use base64::Engine;
use cowfiles::cowfiles_manager_client::CowfilesManagerClient;
use cowfiles::CowfileDescriptor;
#[cfg(feature = "cowserve")]
use cowfiles::{cowfiles_manager_client::CowfilesManagerClient, GetCowfileRequest, GetCowfilesRequest};
#[cfg(feature = "cowserve")]
pub type CowClient = CowfilesManagerClient<tonic::transport::Channel>;

impl serenity::prelude::TypeMapKey for CowClient {
type Value = CowClient;
}

fn decode_base64(data: &str) -> Result<String> {
let decoded = base64::engine::general_purpose::STANDARD.decode(data)?;
let decoded = String::from_utf8(decoded)?;
Ok(decoded)
}

pub async fn connect() -> Result<CowClient> {
#[cfg(feature = "cowserve")]
async fn connect() -> Result<CowClient> {
let client = CowfilesManagerClient::connect(format!("{}", config::get_server_url())).await?;
Ok(client)
}

#[cfg(feature = "cowserve")]
pub async fn get_cowfiles(server_id: Option<String>) -> Result<Vec<CowfileDescriptor>> {
let mut client = connect().await?;
let resp = client
Expand All @@ -31,6 +34,7 @@ pub async fn get_cowfiles(server_id: Option<String>) -> Result<Vec<CowfileDescri
Ok(resp.into_inner().cowfiles)
}

#[cfg(feature = "cowserve")]
pub async fn get_cowfile(id: &str) -> Result<String> {
let mut client = connect().await?;
client
Expand All @@ -39,6 +43,47 @@ pub async fn get_cowfile(id: &str) -> Result<String> {
.and_then(|res| Ok(decode_base64(&res.get_ref().data)))?
}

#[cfg(feature = "cowserve")]
pub async fn get_cowfile_by_name(server_id: Option<String>, name: &str) -> Result<String> {
let cowfiles = get_cowfiles(server_id).await?;
let cowfile = cowfiles
.into_iter()
.find(|cowfile| cowfile.name == name)
.ok_or(anyhow!("Character not found"))?;

get_cowfile(&cowfile.id).await
}

#[cfg(not(feature = "cowserve"))]
pub async fn get_cowfiles(_sid: Option<String>) -> Result<Vec<CowfileDescriptor>> {
let mut result = vec![];

builtin::get_builtin().iter().for_each(|chara| {
result.push(CowfileDescriptor {
id: chara.id.clone(),
server_id: None,
name: chara.name.clone(),
author: chara.author.clone(),
uploader_id: chara.uploader_id.clone(),
})
});

Ok(result)
}

#[cfg(not(feature = "cowserve"))]
pub async fn get_cowfile(id: &str) -> Result<String> {
let cowfiles = builtin::get_builtin();
let data = cowfiles
.into_iter()
.find(|cowfile| cowfile.id == id)
.and_then(|res| Some(decode_base64(&res.data).unwrap()))
.ok_or(anyhow!("Character not found"))?;

Ok(data)
}

#[cfg(not(feature = "cowserve"))]
pub async fn get_cowfile_by_name(server_id: Option<String>, name: &str) -> Result<String> {
let cowfiles = get_cowfiles(server_id).await?;
let cowfile = cowfiles
Expand Down
Loading

0 comments on commit 2f3f15f

Please sign in to comment.