diff --git a/.github/workflows/deploy-commands.yml b/.github/workflows/deploy-commands.yml new file mode 100644 index 0000000..66a2e84 --- /dev/null +++ b/.github/workflows/deploy-commands.yml @@ -0,0 +1,37 @@ +name: Deploy Discord Commands + +on: + workflow_dispatch: # Manual trigger only + +jobs: + deploy-commands: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Read Node version + run: | + NODE_VERSION=$(cat .nvmrc | sed 's/v//') + echo "NODE_VERSION=$NODE_VERSION" >> $GITHUB_ENV + + - name: Deploy Discord Commands to VPS + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.VPS_HOST }} + username: ${{ secrets.VPS_USER }} + key: ${{ secrets.VPS_SSH_KEY }} + script: | + cd /home/${{ secrets.VPS_USER }}/moderation-tool-bot + + # Read NODE_VERSION from .nvmrc + export NODE_VERSION=$(cat .nvmrc | sed 's/v//') + echo "Using Node version: $NODE_VERSION" + + # Run deploy script inside the already running Docker container + # .env.local file should already exist from main deployment + echo "Deploying Discord commands..." + docker compose --profile prod exec discord-bot node dist/utils/deploy-commands.js + + echo "Discord commands deployment completed!" \ No newline at end of file diff --git a/package.json b/package.json index a9fef89..fa50701 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "format": "biome format --write .", "check": "biome check .", "check:fix": "biome check --write .", + "deploy-commands": "tsx src/utils/deploy-commands.ts", "db:migrate": "prisma migrate dev", "db:validate": "prisma validate", "db:format": "prisma format", diff --git a/src/utils/deploy-commands.ts b/src/utils/deploy-commands.ts new file mode 100644 index 0000000..a638a72 --- /dev/null +++ b/src/utils/deploy-commands.ts @@ -0,0 +1,31 @@ +import { REST, type RESTPutAPIApplicationCommandsResult, Routes } from "discord.js"; +import { commands } from "../commands/index.js"; +import { config } from "../env.js"; + +export async function deployCommands(): Promise { + const commandData = [...commands.values()].map((command) => command.data); + + const rest = new REST({ version: "10" }).setToken(config.discord.token); + + (await rest.put(Routes.applicationCommands(config.discord.clientId), { + body: [], + })) as RESTPutAPIApplicationCommandsResult; + try { + const result = (await rest.put( + Routes.applicationGuildCommands(config.discord.clientId, config.discord.serverId), + { + body: commandData, + } + )) as RESTPutAPIApplicationCommandsResult; + console.log( + `✅ Successfully deployed ${result.length} commands to guild ${config.discord.serverId}` + ); + } catch (error) { + console.error("❌ Error deploying commands:", error); + } +} + +// If run directly with `node deploy.ts` +if (import.meta.url === `file://${process.argv[1]}`) { + deployCommands(); +}