fix: Fix pipeline, add ci and adapted compose
Some checks failed
CI / Run tests (pull_request) Failing after 20s
Some checks failed
CI / Run tests (pull_request) Failing after 20s
This commit is contained in:
@@ -2,15 +2,49 @@ name: CD
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main, v2]
|
branches: [main]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: cd-${{ github.ref_name }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
name: Build and push Docker image
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v7
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v4
|
||||||
|
- name: Log in to Docker Hub
|
||||||
|
uses: docker/login-action@v4
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_TOKEN }}
|
||||||
|
- name: Restore Docker build cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: /tmp/.buildx-cache
|
||||||
|
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-buildx-
|
||||||
|
- name: Build and push image
|
||||||
|
uses: docker/build-push-action@v7
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
${{ secrets.DOCKER_USERNAME }}/botmafieux:latest
|
||||||
|
${{ secrets.DOCKER_USERNAME }}/botmafieux:${{ github.sha }}
|
||||||
|
cache-from: type=local,src=/tmp/.buildx-cache
|
||||||
|
cache-to: type=local,dest=/tmp/.buildx-cache,mode=max
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
name: Deploy to VPS
|
name: Deploy to VPS
|
||||||
needs: build-and-push
|
needs: build-and-push
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Copy files to VPS
|
- name: Copy compose file to VPS
|
||||||
uses: appleboy/scp-action@v1
|
uses: appleboy/scp-action@v1
|
||||||
with:
|
with:
|
||||||
host: ${{ secrets.VPS_HOST }}
|
host: ${{ secrets.VPS_HOST }}
|
||||||
@@ -19,7 +53,6 @@ jobs:
|
|||||||
port: ${{ secrets.VPS_SSH_PORT }}
|
port: ${{ secrets.VPS_SSH_PORT }}
|
||||||
source: "compose.yaml"
|
source: "compose.yaml"
|
||||||
target: "/opt/docker/botmafieux"
|
target: "/opt/docker/botmafieux"
|
||||||
|
|
||||||
- name: Deploy on VPS
|
- name: Deploy on VPS
|
||||||
uses: appleboy/ssh-action@v1
|
uses: appleboy/ssh-action@v1
|
||||||
with:
|
with:
|
||||||
@@ -28,12 +61,7 @@ jobs:
|
|||||||
key: ${{ secrets.VPS_SSH_KEY }}
|
key: ${{ secrets.VPS_SSH_KEY }}
|
||||||
port: ${{ secrets.VPS_SSH_PORT }}
|
port: ${{ secrets.VPS_SSH_PORT }}
|
||||||
script: |
|
script: |
|
||||||
|
set -euo pipefail
|
||||||
cd /opt/docker/botmafieux
|
cd /opt/docker/botmafieux
|
||||||
|
docker compose -f compose.yaml --env-file .env pull
|
||||||
docker compose -f compose.yaml --env-file .env down
|
docker compose -f compose.yaml --env-file .env up -d --remove-orphans
|
||||||
|
|
||||||
docker compose -f compose.yaml --env-file .env build
|
|
||||||
|
|
||||||
docker compose -f compose.yaml --env-file .env up -d
|
|
||||||
|
|
||||||
docker compose -f compose.yaml --env-file .env.prod ps
|
|
||||||
|
|||||||
22
.gitea/workflows/ci.yaml
Normal file
22
.gitea/workflows/ci.yaml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Run tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v7
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: 3.13
|
||||||
|
- name: Install dependencies
|
||||||
|
run: python -m pip install --no-cache-dir -r requirements.txt
|
||||||
|
- name: Run pytest
|
||||||
|
run: pytest -q
|
||||||
25
compose.yaml
25
compose.yaml
@@ -1,9 +1,22 @@
|
|||||||
|
networks:
|
||||||
|
internal:
|
||||||
|
internal: true
|
||||||
|
outbound:
|
||||||
|
external: true
|
||||||
|
|
||||||
services:
|
services:
|
||||||
botmafieux:
|
botmafieux:
|
||||||
build:
|
image: nebulo9/botmafieux:latest
|
||||||
context: .
|
|
||||||
dockerfile: ./Dockerfile
|
|
||||||
tags:
|
|
||||||
- nebulo9/botmafieux:v2
|
|
||||||
container_name: botmafieux
|
container_name: botmafieux
|
||||||
env_file: ./.env
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
- outbound
|
||||||
|
env_file: ./.env
|
||||||
|
volumes:
|
||||||
|
- ./config:/config
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '0.25'
|
||||||
|
memory: '256M'
|
||||||
|
|||||||
6778
config/hltv.html
Normal file
6778
config/hltv.html
Normal file
File diff suppressed because one or more lines are too long
27
config/insults.txt
Normal file
27
config/insults.txt
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
Ta gueule.
|
||||||
|
Qui a demandé ?
|
||||||
|
Mais tais-toi!
|
||||||
|
zZzZzZzZ......
|
||||||
|
Tout ça ?
|
||||||
|
On peut se passer du message je pense.
|
||||||
|
C'est chiant le message là.
|
||||||
|
Mdr on s'en fout.
|
||||||
|
Pas lu.
|
||||||
|
Trop long j'ai décroché.
|
||||||
|
Il faut quitter le serveur, vous gênez l'espace s'il vous plaît.
|
||||||
|
Gênant...
|
||||||
|
Si je devais noter la pertinence du message ce serait genre 1/10.
|
||||||
|
Tu es ridicule, arrête d'écrire.
|
||||||
|
Ça a intéréssé quelqu'un ?
|
||||||
|
Franchement c'était nécessaire d'écrire ça ?
|
||||||
|
Honestly the most useless thing I read today.
|
||||||
|
Dommage que les hommes soient cons…
|
||||||
|
Ta mère mérite la prison pour avoir mis au monde un HOMME.
|
||||||
|
T'as pas beaucoup de neurones.
|
||||||
|
Arrêtons de normaliser les hommes svp.
|
||||||
|
🚮🚮
|
||||||
|
Ton message me donne envie de vomir.
|
||||||
|
J'ai pas ri perso.
|
||||||
|
Tiens tiens encore une raison de détester les hommes !
|
||||||
|
Y'a moyen ton père c'est Macron.
|
||||||
|
Tu préfères devenir un être humain sympa ou rester un homme ?
|
||||||
1
config/intern.json
Normal file
1
config/intern.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"mentor_id": 264189554582355969, "guild_id": 897157935006900254, "next_roll": "2026-07-22T00:00:00"}]
|
||||||
22
config/intern_takes.csv
Normal file
22
config/intern_takes.csv
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
target;weight;take
|
||||||
|
any;1.0;Tu as besoin d'un café ?
|
||||||
|
any;1.0;Je peux te faire un café si tu veux ?
|
||||||
|
any;1.0;Tu as besoin d'un thé ?
|
||||||
|
any;1.0;Je peux te faire un thé si tu veux ?
|
||||||
|
any;1.0;Tu as besoin d'un matcha latte?
|
||||||
|
any;1.0;Je peux te faire un matcha latte si tu veux ?
|
||||||
|
any;1.0;Tu peux m'aider sur un truc ?
|
||||||
|
any;1.0;Désolé, j'ai pas compris.
|
||||||
|
any;1.0;Attends, tu peux réexpliquer ?
|
||||||
|
any;1.0;J'ai fait une bêtise je crois...
|
||||||
|
nebulo;2.0;J'ai un bug dans mon code tu peux regarder ?
|
||||||
|
bluebro;2.0;J'ai un bug dans mon code tu peux regarder ?
|
||||||
|
viebah;2.0;J'ai un bug dans mon code tu peux regarder ?
|
||||||
|
merdix;2.0;Mon modèle 3D est cassé, je fais quoi ?
|
||||||
|
goupzy;2.0;Mon modèle 3D est cassé, je fais quoi ?
|
||||||
|
viebah;2.0;Mon modèle 3D est cassé, je fais quoi ?
|
||||||
|
goupzy;2.0;Mon modèle 3D est cassé, je fais quoi ?
|
||||||
|
nino274;2.0;Mon modèle 3D est cassé, je fais quoi ?
|
||||||
|
cemesah;2.0;J'ai fait une erreur, il faut réimprimer les cartes...
|
||||||
|
cemesah;2.0;J'ai pas sauvegardé et InDesign a planté...
|
||||||
|
cemesah;2.0;Tu veux du bouillon ?
|
||||||
|
78
tests/test_intern_voice.py
Normal file
78
tests/test_intern_voice.py
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import unittest
|
||||||
|
from types import SimpleNamespace
|
||||||
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
|
from cogs.intern import InternCog
|
||||||
|
|
||||||
|
|
||||||
|
class InternVoiceBehaviorTests(unittest.TestCase):
|
||||||
|
def make_cog(self, voice_client=None):
|
||||||
|
cog = InternCog.__new__(InternCog)
|
||||||
|
cog.bot = SimpleNamespace(voice_clients=[voice_client] if voice_client else [])
|
||||||
|
cog.data = [{"guild_id": 123, "mentor_id": 456}]
|
||||||
|
cog.connected_guild_ids = set()
|
||||||
|
cog.in_voice_channel = False
|
||||||
|
return cog
|
||||||
|
|
||||||
|
def make_channel(self, channel_id, guild, connect_mock=None, name="test-channel"):
|
||||||
|
return SimpleNamespace(id=channel_id, guild=guild, connect=connect_mock or AsyncMock(), name=name)
|
||||||
|
|
||||||
|
def make_member(self, member_id):
|
||||||
|
return SimpleNamespace(id=member_id)
|
||||||
|
|
||||||
|
async def _run_handler(self, cog, before_channel, after_channel, voice_client):
|
||||||
|
before = SimpleNamespace(channel=before_channel)
|
||||||
|
after = SimpleNamespace(channel=after_channel)
|
||||||
|
member = self.make_member(456)
|
||||||
|
await cog.on_voice_state_update(member, before, after)
|
||||||
|
|
||||||
|
def test_initial_join_only_connects_with_25_percent_chance(self):
|
||||||
|
cog = self.make_cog()
|
||||||
|
connect_mock = AsyncMock()
|
||||||
|
guild = SimpleNamespace(id=123, voice_client=None)
|
||||||
|
channel = self.make_channel(1, guild, connect_mock=connect_mock)
|
||||||
|
before = None
|
||||||
|
after = SimpleNamespace(channel=channel)
|
||||||
|
member = self.make_member(456)
|
||||||
|
|
||||||
|
with patch("cogs.intern.random.random", return_value=0.1):
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(cog.on_voice_state_update(member, before, after))
|
||||||
|
connect_mock.assert_awaited_once()
|
||||||
|
|
||||||
|
cog = self.make_cog()
|
||||||
|
connect_mock = AsyncMock()
|
||||||
|
guild = SimpleNamespace(id=123, voice_client=None)
|
||||||
|
channel = self.make_channel(1, guild, connect_mock=connect_mock)
|
||||||
|
before = None
|
||||||
|
after = SimpleNamespace(channel=channel)
|
||||||
|
member = self.make_member(456)
|
||||||
|
|
||||||
|
with patch("cogs.intern.random.random", return_value=0.9):
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(cog.on_voice_state_update(member, before, after))
|
||||||
|
connect_mock.assert_not_awaited()
|
||||||
|
|
||||||
|
def test_move_always_moves_the_bot_when_connected(self):
|
||||||
|
guild = SimpleNamespace(id=123, voice_client=None)
|
||||||
|
voice_client = SimpleNamespace(move_to=AsyncMock(), disconnect=AsyncMock(), guild=guild)
|
||||||
|
cog = self.make_cog(voice_client=voice_client)
|
||||||
|
before_channel = self.make_channel(1, guild)
|
||||||
|
after_channel = self.make_channel(2, guild)
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(self._run_handler(cog, before_channel, after_channel, voice_client))
|
||||||
|
voice_client.move_to.assert_awaited_once_with(after_channel)
|
||||||
|
|
||||||
|
def test_disconnect_always_disconnects_when_mentor_leaves(self):
|
||||||
|
guild = SimpleNamespace(id=123, voice_client=None)
|
||||||
|
voice_client = SimpleNamespace(move_to=AsyncMock(), disconnect=AsyncMock(), guild=guild)
|
||||||
|
cog = self.make_cog(voice_client=voice_client)
|
||||||
|
before_channel = self.make_channel(1, guild)
|
||||||
|
after_channel = None
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(self._run_handler(cog, before_channel, after_channel, voice_client))
|
||||||
|
voice_client.disconnect.assert_awaited_once_with(force=True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user