diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml new file mode 100644 index 0000000..9cc6116 --- /dev/null +++ b/.github/workflows/docker.yaml @@ -0,0 +1,63 @@ +name: Build and Push Docker Image + +on: + push: + branches: + - main + +jobs: + make-cache: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Make Cache + uses: Swatinem/rust-cache@v2.7.3 + with: + save-if: true + cache-all-crates: true + shared-key: tests + - name: Update Toolchain + run: rustup toolchain install stable --profile minimal --no-self-update + - name: Job + run: cargo build + + Clippy: + needs: make-cache + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Load Cache + uses: Swatinem/rust-cache@v2.7.3 + with: + # save-if: false + shared-key: tests + key: clippy + - name: Update Toolchain + run: rustup toolchain install stable --profile minimal --no-self-update + - name: Job + run: cargo clippy -- -D warnings + + build: + needs: + - Clippy + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + - name: Login to GitHub Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker image + uses: docker/build-push-action@v2 + with: + context: . + file: Dockerfile + push: true + tags: ghcr.io/${{ github.repository }}/shuller:latest \ No newline at end of file diff --git a/.gitignore b/.gitignore index d365fd8..08e8531 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target .env .DS_store +Cargo.lock \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index b9729b4..a745e2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,14 @@ tokio = { version = "1.39.2", features = ["full"] } tracing = "0.1.40" tracing-subscriber = "0.3.18" url = "2.5.2" + + +[profile.dev] +opt-level = 1 +debug = true + +[profile.release] +strip = true +opt-level = 3 +lto = true +debug = false diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..539b799 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,48 @@ +# -- Этап сборки бинарника -- +FROM rust:1.80.1-alpine AS base + +RUN apk add --no-cache musl-dev openssl-dev + +ENV RUSTFLAGS="-C target-feature=-crt-static" + +RUN cargo install sccache +RUN cargo install cargo-chef + +ENV RUSTC_WRAPPER=sccache SCCACHE_DIR=/sccache + +FROM base AS planner +WORKDIR /app +COPY . . +RUN --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=$SCCACHE_DIR,sharing=locked \ + cargo chef prepare --recipe-path recipe.json + +FROM base AS builder +WORKDIR /app +# set up sccache +COPY --from=planner /app/recipe.json recipe.json +RUN --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=$SCCACHE_DIR,sharing=locked \ + cargo chef cook --release --recipe-path recipe.json +# copy project +COPY . . +# build +RUN --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=$SCCACHE_DIR,sharing=locked \ + cargo build --release + +# -- Этап итоговой сборки -- + +# Используем минимальный Alpine образ для конечного контейнера +FROM alpine:latest + +# Устанавливаем рабочую директорию внутри контейнера +WORKDIR /app + +# Устанавливаем необходимые зависимости для запуска +RUN apk add --no-cache ca-certificates libgcc + +# Копируем собранный бинарный файл из стадии сборки +COPY --from=builder /app/target/release/shuller_bot . +# Указываем команду запуска +CMD ["./shuller_bot"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..912a193 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,7 @@ +version: '3.8' + +services: + shuller_bot: + image: shuller_bot:latest + environment: + - DS_TOCKEN=YOUR_TOKEN diff --git a/src/main.rs b/src/main.rs index e1bfd7e..3906b6f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,8 +51,15 @@ async fn main() { name: "Проповедничает Shuller".to_string(), kind: serenity::ActivityType::Custom, state: Some("Едет в kfc, жарить кур".to_string()), - url: Some(Url::parse("https://crates.io/crates/shuller").unwrap()), + url: Some( + Url::parse("https://crates.io/crates/shuller") + .expect("Fail to build url for activity"), + ), }) .await; - client.unwrap().start_autosharded().await.unwrap(); + client + .expect("Fail to build client") + .start_autosharded() + .await + .expect("Fail to build client"); }