Skip to content

Commit

Permalink
3.4.0
Browse files Browse the repository at this point in the history
Added tests for audio services
Added GitHub Action for running tests.
Now Docker Image building depends on tests completion.
  • Loading branch information
AlexInCube authored Aug 3, 2024
1 parent 990fbc7 commit c4cbd2a
Show file tree
Hide file tree
Showing 14 changed files with 310 additions and 47 deletions.
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ BOT_FFMPEG_LOGGING=false
BOT_COMMAND_PREFIX=//
BOT_LANGUAGE=en

BOT_MAX_SONGS_IN_QUEUE=500

BOT_DISCORD_TOKEN=undefined
BOT_DISCORD_CLIENT_ID=undefined
BOT_DISCORD_OVERPOWERED_ID=undefined
Expand Down
11 changes: 4 additions & 7 deletions .github/workflows/publish-docker-image.yaml
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
name: Publish Docker image

on:
push:
workflow_run:
workflows: [ "tests", "linters" ]
types: ['completed']
branches: ['master']
paths-ignore:
- '**/wiki/**'
- '/wiki/**'
- 'docker-compose.yml'
- '.env'
- '*.sh'

env:
IMAGE_TAG: alexincube/aicotest

jobs:
push_to_registry:
if: github.event.workflow_run.event == 'push' && github.event.workflow_run.conclusion == 'success'
name: Push Docker image to Docker Hub
runs-on: ubuntu-latest
steps:
Expand Down
36 changes: 36 additions & 0 deletions .github/workflows/quality.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Code Quality

on:
push:
branches: ['**']
pull_request:
branches: ['**']

jobs:
linters:
name: Run Linters
runs-on: ubuntu-latest

steps:
- name: Check out Git repository
uses: actions/checkout@v4

- name: Setup PNPM
uses: pnpm/action-setup@v4
with:
version: 9

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: "pnpm"

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Run Prettier
run: pnpm run prettier:check

- name: Run ESLint
run: pnpm run eslint
55 changes: 55 additions & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Tests

on:
push:
branches: ['**']
paths-ignore:
- '**/wiki/**'
- '/wiki/**'
- 'docker-compose.yml'
- '.env'
- '*.sh'
pull_request:
branches: ['**']
paths-ignore:
- '**/wiki/**'
- '/wiki/**'
- 'docker-compose.yml'
- '.env'
- '*.sh'

jobs:
tests:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup PNPM
uses: pnpm/action-setup@v4
with:
version: 9

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: "pnpm"

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Make env file
run: |
pwd
touch .env.development
echo '${{ secrets.ENV_DEVELOPMENT }}' > .env.development
- name: Make yt-cookies.json
run: |
touch yt-cookies.json
echo '${{ secrets.YOUTUBE_COOKIES }}' > yt-cookies.json
- name: Run tests
run: pnpm run test
11 changes: 6 additions & 5 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export default tseslint.config(eslint.configs.recommended, ...tseslint.configs.r
plugins: {
'typescript-eslint': ParserTypeScript,
prettier: prettierPlugin
}, ignores: ['build', 'node_modules', 'coverage', 'eslint.config.js'],
},
ignores: ['build', 'node_modules', 'coverage', 'eslint.config.js'],
languageOptions: {
globals: {
...globals.node,
Expand All @@ -20,12 +21,12 @@ export default tseslint.config(eslint.configs.recommended, ...tseslint.configs.r
}
},
rules: {
...prettierPlugin.configs.recommended.rules,
...eslintConfigPrettier.rules,
...prettierPlugin.configs.recommended.rules,
...eslintConfigPrettier.rules,
'@typescript-eslint/no-var-requires': 0,
'@typescript-eslint/no-non-null-assertion': 0,
'@typescript-eslint/no-explicit-any': "warn",
'@typescript-eslint/no-explicit-any': 'warn',
'prettier/prettier': ['error', { endOfLine: 'auto' }],
'no-constant-binary-expression': "off"
'no-constant-binary-expression': 'off'
}
});
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
{
"name": "aicbot",
"version": "3.3.1",
"version": "3.4.0",
"description": "Discord Bot for playing music",
"main": "build/main.js",
"scripts": {
"build": "tsc",
"development": "tsc&& cross-env NODE_ENV=development node build/main.js",
"production": "cross-env NODE_ENV=production node build/main.js",
"cookies_grabbing": "cross-env NODE_ENV=development node build/Script_getCookie.js"
"cookies_grabbing": "cross-env NODE_ENV=development node build/Script_getCookie.js",
"test": "tsc&& cross-env NODE_ENV=development node --test",
"eslint": "eslint \"src/**/*.{ts,js}\"",
"prettier:format": "prettier --write \"**/*.{ts,js}\"",
"prettier:check": "prettier --check \"**/*.{ts,js}\""
},
"type": "module",
"keywords": [],
Expand Down
13 changes: 13 additions & 0 deletions src/ClientIntents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { GatewayIntentBits } from 'discord.js';

export const clientIntents: Array<GatewayIntentBits> = [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildPresences,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildVoiceStates,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.DirectMessages,
GatewayIntentBits.DirectMessageTyping,
GatewayIntentBits.GuildModeration
];
1 change: 0 additions & 1 deletion src/CookiesAutomation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export async function getYoutubeCookie() {

const browser = await puppeteer.launch({
headless: true,
slowMo: 2000,
args: ['--remote-debugging-port=9222', '--remote-debugging-address=0.0.0.0', '--no-sandbox']
});
const page = await browser.newPage();
Expand Down
25 changes: 22 additions & 3 deletions src/EnvironmentVariables.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
import { z } from 'zod';
import * as dotenv from 'dotenv';
import { loggerSend } from './utilities/logger.js';
import path from 'path';
import fs from 'fs';

const loggerPrefixEnv = 'ENV';

dotenv.config({ path: `.env.${process.env.NODE_ENV}` });
const envPath = path.resolve(process.cwd(), `.env.${process.env.NODE_ENV}`);

loggerSend(`Checking environment variables in ${envPath}`, loggerPrefixEnv);
if (fs.existsSync(envPath)) {
dotenv.config({ path: envPath });
loggerSend(`Environment variables is found in ${envPath}`, loggerPrefixEnv);
} else {
loggerSend(
`Environment variables are not found in ${envPath}, trying to load variables from OS environment variables`,
loggerPrefixEnv
);
}

const envVariables = z.object({
NODE_ENV: z.enum(['development', 'production']),
NODE_ENV: z.enum(['development', 'production']).default('development'),

BOT_VERBOSE_LOGGING: z
.preprocess(
Expand Down Expand Up @@ -37,6 +50,8 @@ const envVariables = z.object({
BOT_LANGUAGE: z.enum(['en', 'ru']).optional().default('en'),
BOT_COMMAND_PREFIX: z.string().min(1),

BOT_MAX_SONGS_IN_QUEUE: z.coerce.number().positive().min(1).optional().default(500),

MONGO_URI: z.string(),
MONGO_DATABASE_NAME: z.string(),

Expand All @@ -61,4 +76,8 @@ const envVariables = z.object({

export const ENV = envVariables.parse(process.env);

loggerSend(`Loaded .env.${process.env.NODE_ENV}`, loggerPrefixEnv);
if (fs.existsSync(envPath)) {
loggerSend(`Environment variables is loaded from ${envPath}`, loggerPrefixEnv);
} else {
loggerSend(`Environment variables is loaded from OS environment variables`, loggerPrefixEnv);
}
30 changes: 19 additions & 11 deletions src/audioplayer/AudioPlayerCore.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { DisTube, PlayOptions, Queue, RepeatMode, Song, Events as DistubeEvents, Playlist } from 'distube';
import {
DisTube,
PlayOptions,
Queue,
RepeatMode,
Song,
Events as DistubeEvents,
Playlist
} from 'distube';
import { AudioPlayersManager } from './AudioPlayersManager.js';
import { pagination } from '../utilities/pagination/pagination.js';
import { ButtonStyles, ButtonTypes } from '../utilities/pagination/paginationTypes.js';
Expand All @@ -25,8 +33,6 @@ import { joinVoiceChannel } from '@discordjs/voice';
import { generateWarningEmbed } from '../utilities/generateWarningEmbed.js';
import { generateLyricsEmbed } from './Lyrics.js';

export const queueSongsLimit = 500;

export const loggerPrefixAudioplayer = `Audioplayer`;

const plugins = await LoadPlugins();
Expand Down Expand Up @@ -58,7 +64,7 @@ export class AudioPlayerCore {
options?: PlayOptions
) {
try {
const playableThing: Song | Playlist = await this.distube.handler.resolve(song)
const playableThing: Song | Playlist = await this.distube.handler.resolve(song);

// I am need manual connect user to a voice channel, because when I am using only Distube "play"
// method, getVoiceConnection in @discordjs/voice is not working
Expand All @@ -72,13 +78,15 @@ export class AudioPlayerCore {
} catch (e) {
if (ENV.BOT_VERBOSE_LOGGING) loggerError(e);
await textChannel.send({
embeds: [generateErrorEmbed(`${song}\n${e.message}`, i18next.t('audioplayer:play_error') as string)]
embeds: [
generateErrorEmbed(`${song}\n${e.message}`, i18next.t('audioplayer:play_error') as string)
]
});

const queue = this.distube.getQueue(voiceChannel.guildId)
const queue = this.distube.getQueue(voiceChannel.guildId);

if (!queue) return
if (queue.songs.length === 0) await this.stop(voiceChannel.guild)
if (!queue) return;
if (queue.songs.length === 0) await this.stop(voiceChannel.guild);
}
}

Expand Down Expand Up @@ -362,17 +370,17 @@ export class AudioPlayerCore {
if (!queue.textChannel) return;

await queue.textChannel.send({ embeds: [generateAddedPlaylistMessage(playlist)] });
if (queue.songs.length >= queueSongsLimit) {
if (queue.songs.length >= ENV.BOT_MAX_SONGS_IN_QUEUE) {
await queue.textChannel.send({
embeds: [
generateWarningEmbed(
i18next.t('audioplayer:event_add_list_limit', {
queueLimit: queueSongsLimit
queueLimit: ENV.BOT_MAX_SONGS_IN_QUEUE
}) as string
)
]
});
queue.songs.length = queueSongsLimit;
queue.songs.length = ENV.BOT_MAX_SONGS_IN_QUEUE;
}

const player = this.playersManager.get(queue.id);
Expand Down
Loading

0 comments on commit c4cbd2a

Please sign in to comment.