diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..fa8b5bd --- /dev/null +++ b/.dockerignore @@ -0,0 +1,100 @@ +.Python +[Bb]in +[Ii]nclude +[Ll]ib +[Ll]ib64 +[Ll]ocal +[Ss]cripts +pyvenv.cfg +.venv +pip-selfcheck.json +.idea +*.iml +out +gen +*.zwc +*.zwc.old +*zcompdump* +.zsh_history +.zsh_sessions +.zcalc_history +._zinit +.zinit_lstupd +zsdoc/data +.directory_history +/tests/_output/* +!/tests/_output/.gitkeep +__pycache__/ +*.py[cod] +*$py.class +*.so +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST +*.manifest +*.spec +pip-log.txt +pip-delete-this-directory.txt +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ +*.mo +*.pot +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal +instance/ +.webassets-cache +.scrapy +docs/_build/ +.pybuilder/ +target/ +.ipynb_checkpoints +profile_default/ +ipython_config.py +.pdm.toml +__pypackages__/ +celerybeat-schedule +celerybeat.pid +*.sage.py +.env +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +.spyderproject +.spyproject +.ropeproject +/site +.mypy_cache/ +.dmypy.json +dmypy.json +.pyre/ +.pytype/ +cython_debug/ \ No newline at end of file diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..f50bc60 --- /dev/null +++ b/.env.example @@ -0,0 +1,12 @@ +# Bot Configuration +BOT_TOKEN=your_telegram_bot_token_here +DATABASE_NAME=playlist.db +ADD_TRACK_TIME_WINDOW=60 +LOG_LEVEL=INFO + +# GitHub Actions Secrets (set these in repository settings > Secrets and variables > Actions) +# DOCKER_USERNAME=your_docker_hub_username +# DOCKER_PASSWORD=your_docker_hub_password_or_token +# SERVER_HOST=your_server_ip_or_hostname +# SERVER_USER=your_server_ssh_username +# SERVER_SSH_KEY=your_private_ssh_key_content diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml new file mode 100644 index 0000000..50a1136 --- /dev/null +++ b/.github/workflows/ci-cd.yml @@ -0,0 +1,102 @@ +name: CI/CD Pipeline + +on: + push: + branches: [ main ] + tags: + - "v*.*.*" + pull_request: + branches: [ main ] + +jobs: + build: + runs-on: ubuntu-latest + environment: prod + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image + run: | + docker buildx build --platform linux/amd64 -t bilbomusicbot:latest --load . + + - name: Test Docker image + run: | + docker run --rm -e BOT_TOKEN=${{ secrets.BOT_TOKEN }} bilbomusicbot:latest python -c " + try: + import bot + print('Bot module imported successfully') + except Exception as e: + print(f'Import failed: {e}') + exit(1) + " + + release: + needs: build + runs-on: ubuntu-latest + environment: prod + if: startsWith(github.ref, 'refs/tags/v') + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + # if your server support ssh key use this format + # key: ${{ secrets.SERVER_SSH_KEY }} + + - name: Build and push Docker image + run: | + docker buildx build --platform linux/amd64,linux/arm64 \ + -t ${{ secrets.DOCKER_USERNAME }}/bilbomusicbot:latest \ + -t ${{ secrets.DOCKER_USERNAME }}/bilbomusicbot:${{ github.ref_name }} \ + --push . + + - name: Copy docker-compose.yml to server + uses: appleboy/scp-action@v0.1.7 + with: + host: ${{ secrets.SERVER_HOST }} + username: ${{ secrets.SERVER_USER }} + password: ${{ secrets.SERVER_SSH_KEY }} + source: "docker-compose.yml" + target: "/opt/bilbomusicbot/" + + - name: Prepare server for deployment + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.SERVER_HOST }} + username: ${{ secrets.SERVER_USER }} + password: ${{ secrets.SERVER_SSH_KEY }} + script: | + mkdir -p /opt/bilbomusicbot + cd /opt/bilbomusicbot + docker pull ${{ secrets.DOCKER_USERNAME }}/bilbomusicbot:latest + + deploy: + needs: release + runs-on: ubuntu-latest + environment: prod + if: startsWith(github.ref, 'refs/tags/v') + steps: + - name: Deploy to server + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.SERVER_HOST }} + username: ${{ secrets.SERVER_USER }} + password: ${{ secrets.SERVER_SSH_KEY }} + script: | + cd /opt/bilbomusicbot + export DOCKER_USERNAME=${{ secrets.DOCKER_USERNAME }} + export BOT_TOKEN=${{ secrets.BOT_TOKEN }} + docker compose down + docker compose up -d + docker system prune -f \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..82447c4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM python:3.13-slim + +WORKDIR /app + +COPY requirements.txt . + +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +CMD ["python", "bot.py"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4e077ba --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,18 @@ +services: + bilbomusicbot: + image: ${DOCKER_USERNAME}/bilbomusicbot:latest + container_name: bilbomusicbot + restart: unless-stopped + environment: + - BOT_TOKEN=${BOT_TOKEN} + volumes: + - ./data:/app/data + networks: + - bilbonet + +networks: + bilbonet: + driver: bridge + +volumes: + data: \ No newline at end of file