Skip to content

Commit 8f5203d

Browse files
committed
feat: refactor
1 parent 7b2ca29 commit 8f5203d

42 files changed

Lines changed: 515 additions & 510 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dockerignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
target/
2+
.git/
3+
.gitignore
4+
Dockerfile
5+
docker-compose.yml

.github/workflows/build_and_update.yml

Lines changed: 0 additions & 53 deletions
This file was deleted.

.github/workflows/release.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
pull_request:
7+
branches: ["main"]
8+
workflow_dispatch:
9+
10+
concurrency:
11+
group: "release"
12+
cancel-in-progress: true
13+
14+
env:
15+
CARGO_TERM_COLOR: always
16+
17+
jobs:
18+
build:
19+
name: Release Docker image
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: actions/checkout@v5
23+
24+
- name: Get Git SHA
25+
id: git_sha
26+
run: |
27+
echo "full=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
28+
29+
- name: Set up Docker Buildx
30+
uses: docker/setup-buildx-action@v3
31+
32+
- name: Login to Docker Hub
33+
uses: docker/login-action@v3
34+
with:
35+
username: ${{ secrets.DOCKER_HUB_USERNAME }}
36+
password: ${{ secrets.DOCKER_HUB_TOKEN }}
37+
38+
- name: Build and push
39+
uses: docker/build-push-action@v6
40+
with:
41+
context: .
42+
push: true
43+
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/${{ vars.DOCKER_IMAGE_NAME }}:latest
44+
build-args: |
45+
GIT_COMMIT=${{ steps.git_sha.outputs.full }}
46+
47+
post:
48+
name: Remote deployment
49+
runs-on: ubuntu-latest
50+
needs: [build]
51+
steps:
52+
- uses: KessokuTeaTime/action-kessoku-private-ci@main
53+
with:
54+
auth: ${{ secrets.KTT_API_TOKEN }}
55+
endpoint: ${{ vars.KTT_API_ENDPOINT }}
56+
payload: |
57+
{
58+
"service_label": "${{ vars.SERVICE_LABEL }}"
59+
}

Cargo.toml

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ sea-orm = { version = "1.1.14", features = [
3939
"with-json",
4040
] }
4141
toml = "0.9.5"
42+
config-file = "0.2.3"
4243

4344
[build-dependencies]
4445
anyhow = "1.0.98"
@@ -71,11 +72,31 @@ future-not-send = "warn"
7172
if-not-else = "warn"
7273
if-then-some-else-none = "warn"
7374
impl-trait-in-params = "warn"
74-
macro-use-imports = "forbid"
75+
macro-use-imports = "deny"
7576
exhaustive-enums = "warn"
7677
str-to-string = "warn"
7778
iter-without-into-iter = "warn"
7879
decimal-literal-representation = "warn"
80+
ref-as-ptr = "warn"
81+
unused-trait-names = "warn"
82+
unnecessary-semicolon = "warn"
83+
unnecessary-debug-formatting = "warn"
84+
too-long-first-doc-paragraph = "warn"
85+
ref-option = "warn"
86+
redundant-test-prefix = "warn"
87+
map-with-unused-argument-over-ranges = "warn"
88+
manual-midpoint = "warn"
89+
manual-is-power-of-two = "warn"
90+
ip-constant = "warn"
91+
elidable-lifetime-names = "warn"
92+
coerce-container-to-any = "warn"
93+
todo = "warn"
94+
inline-always = "warn"
95+
# multiple-crate-versions = "warn"
96+
use-self = "warn"
97+
useless-let-if-seq = "warn"
98+
suboptimal-flops = "warn"
99+
redundant-clone = "warn"
79100

80101
[profile.release]
81102
opt-level = 3

Dockerfile

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# rust builder
2+
3+
FROM rust:bookworm AS rust_builder
4+
5+
ARG GIT_COMMIT
6+
7+
ENV GIT_COMMIT=$GIT_COMMIT
8+
9+
WORKDIR /app
10+
11+
COPY rust-toolchain.toml ./
12+
RUN rustup toolchain install --profile minimal $(grep "channel" rust-toolchain.toml | cut -d'"' -f2)
13+
14+
COPY . .
15+
RUN cargo build --release
16+
17+
# runtime image
18+
19+
FROM debian:bookworm-slim
20+
21+
WORKDIR /app
22+
23+
COPY --from=rust_builder /app/target/release/api-main .
24+
RUN apt-get update && \
25+
apt-get install -y ca-certificates curl gnupg lsb-release && \
26+
install -m 0755 -d /etc/apt/keyrings && \
27+
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \
28+
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" \
29+
> /etc/apt/sources.list.d/docker.list && \
30+
apt-get update && \
31+
apt-get install -y docker-ce-cli && \
32+
rm -rf /var/lib/apt/lists/*
33+
34+
# commands
35+
36+
EXPOSE 8080
37+
38+
CMD ["./api-wordle"]

build.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ use vergen::{BuildBuilder, CargoBuilder, Emitter, RustcBuilder, SysinfoBuilder};
77

88
fn main() -> Result<(), Error> {
99
{
10-
let output = Command::new("git")
11-
.args(["rev-parse", "HEAD"])
12-
.output()
13-
.unwrap();
14-
let hash = String::from_utf8(output.stdout).unwrap();
15-
println!("cargo:rustc-env=GIT_HASH={}", hash);
10+
let git_hash = std::env::var("GIT_COMMIT").unwrap_or_else(|_| {
11+
let output = Command::new("git")
12+
.args(["rev-parse", "HEAD"])
13+
.output()
14+
.unwrap();
15+
String::from_utf8(output.stdout).unwrap()
16+
});
17+
println!("cargo:rustc-env=GIT_HASH={}", git_hash.trim());
1618
}
1719

1820
{

entity/src/entities/histories.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,42 @@
11
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.14
22
3+
#![allow(clippy::exhaustive_enums, unused_qualifications)]
4+
35
use std::fmt::Display;
46

57
use crate::{HISTORY_MAX_TRIES, PUZZLE_LETTERS_COUNT, PuzzleDate, PuzzleSolution, SubmitHistory};
68

79
use sea_orm::entity::prelude::*;
810
use serde::{Deserialize, Serialize};
911

12+
/// The `histories` table model.
1013
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, DeriveEntityModel)]
1114
#[sea_orm(table_name = "histories")]
1215
pub struct Model {
16+
/// The puzzle date.
1317
#[sea_orm(primary_key, auto_increment = false)]
1418
pub date: PuzzleDate,
19+
/// The session token.
1520
#[sea_orm(primary_key, auto_increment = false)]
1621
pub session: String,
22+
/// The submit history in JSON format.
1723
#[sea_orm(column_type = "JsonBinary", nullable)]
1824
pub submit_history: Option<SubmitHistory>,
19-
pub original_solution: PuzzleSolution,
20-
pub is_dirty: bool,
25+
/// The solution submitted.
26+
pub solution: PuzzleSolution,
27+
/// Whether the puzzle has been completed.
2128
pub is_completed: bool,
29+
/// The timestamp when this history was uploaded.
2230
pub uploaded_at: DateTime,
2331
}
2432

2533
impl Model {
34+
/// Returns the number of letters in the puzzle.
2635
pub fn letters_count(&self) -> usize {
2736
PUZZLE_LETTERS_COUNT
2837
}
2938

39+
/// Returns the number of remaining tries.
3040
pub fn remaining_tries(&self) -> usize {
3141
match &self.submit_history {
3242
Some(submit_history) => submit_history.remaining_tries(),
@@ -39,19 +49,16 @@ impl Display for Model {
3949
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4050
write!(
4151
f,
42-
"{:?} -> {} [{} {}] {{{}}} at {}",
43-
self.submit_history,
44-
self.original_solution,
45-
self.date,
46-
if self.is_dirty { "*" } else { "~" },
47-
self.session,
48-
self.uploaded_at
52+
"{:?} -> {} at {} [{}] {{{}}}",
53+
self.submit_history, self.solution, self.uploaded_at, self.date, self.session
4954
)
5055
}
5156
}
5257

58+
/// The relations of the `histories` table.
5359
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
5460
pub enum Relation {
61+
/// The relation to the `puzzles` table.
5562
#[sea_orm(
5663
belongs_to = "super::puzzles::Entity",
5764
from = "Column::Date",
@@ -60,6 +67,7 @@ pub enum Relation {
6067
on_delete = "Cascade"
6168
)]
6269
Puzzles,
70+
/// The relation to the `sessions` table.
6371
#[sea_orm(
6472
belongs_to = "super::sessions::Entity",
6573
from = "Column::Session",

entity/src/entities/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,8 @@ pub mod histories;
66
pub mod puzzles;
77
pub mod sessions;
88

9+
/// The number of letters in the puzzle.
910
pub const PUZZLE_LETTERS_COUNT: usize = 5;
11+
12+
/// The maximum number of tries allowed for a puzzle.
1013
pub const HISTORY_MAX_TRIES: usize = 6;

entity/src/entities/puzzles.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,44 @@
11
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.14
22
3+
#![allow(clippy::exhaustive_enums, unused_qualifications)]
4+
35
use crate::{PUZZLE_LETTERS_COUNT, PuzzleDate, PuzzleSolution};
46

57
use std::fmt::Display;
68

79
use sea_orm::entity::prelude::*;
810
use serde::{Deserialize, Serialize};
911

12+
/// The `puzzles` table model.
1013
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, DeriveEntityModel)]
1114
#[sea_orm(table_name = "puzzles")]
1215
pub struct Model {
16+
/// The puzzle date.
1317
#[sea_orm(primary_key, auto_increment = false)]
1418
pub date: PuzzleDate,
19+
/// The puzzle solution.
1520
pub solution: PuzzleSolution,
16-
pub is_deleted: bool,
1721
}
1822

1923
impl Display for Model {
2024
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21-
write!(
22-
f,
23-
"{} [{} {}]",
24-
self.solution,
25-
self.date,
26-
if self.is_deleted { "-" } else { "+" }
27-
)
25+
write!(f, "{} [{}]", self.solution, self.date,)
2826
}
2927
}
3028

3129
impl Model {
30+
/// Converts this puzzle model into a [`ResultPuzzle`].
3231
pub fn to_result_puzzle(self) -> ResultPuzzle {
3332
self.into()
3433
}
3534
}
3635

36+
/// A puzzle result containing the date and solution.
3737
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
3838
pub struct ResultPuzzle<const N: usize = PUZZLE_LETTERS_COUNT> {
39+
/// The puzzle date.
3940
pub date: PuzzleDate,
41+
/// The puzzle solution.
4042
pub solution: PuzzleSolution<N>,
4143
}
4244

@@ -52,8 +54,10 @@ impl From<Model> for ResultPuzzle<PUZZLE_LETTERS_COUNT> {
5254
}
5355
}
5456

57+
/// The relations of the `puzzles` table.
5558
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
5659
pub enum Relation {
60+
/// The relation to the `histories` table.
5761
#[sea_orm(has_many = "super::histories::Entity")]
5862
Histories,
5963
}

entity/src/entities/sessions.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.14
22
3+
#![allow(clippy::exhaustive_enums, unused_qualifications)]
4+
35
use sea_orm::entity::prelude::*;
46
use serde::{Deserialize, Serialize};
57

8+
/// The `sessions` table model.
69
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, DeriveEntityModel)]
710
#[sea_orm(table_name = "sessions")]
811
pub struct Model {
12+
/// The session token.
913
#[sea_orm(primary_key, auto_increment = false)]
1014
pub session: String,
15+
/// The timestamp when this session was created.
1116
pub created_at: DateTime,
17+
/// The timestamp when this session was last updated.
1218
pub updated_at: DateTime,
1319
}
1420

21+
/// The relations of the `sessions` table.
1522
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
1623
pub enum Relation {
24+
/// The relation to the `histories` table.
1725
#[sea_orm(has_many = "super::histories::Entity")]
1826
Histories,
1927
}

0 commit comments

Comments
 (0)