Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 35 additions & 10 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ version: 2.1
workflows:
main:
jobs:
- go_1-15
- go_1-16
- go_1-17
- go_1-18
- go_1-19
- go_1-20
- go_1-25
- build_docs

commands:
golintci-lint:
description: Run linter checks on TeleIRC.
steps:
- checkout
- run:
- run:
name: Download and install golintci-lint.
command: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sudo sh -s -- -b $(go env GOPATH)/bin v1.43.0
- run:
Expand All @@ -34,21 +35,21 @@ commands:
command: go test -coverprofile=c.out ./...

jobs:
go_1-15:
go_1-18:
docker:
- image: cimg/go:1.15
- image: cimg/go:1.18
steps:
- golintci-lint
- teleirc-test
go_1-16:
go_1-19:
docker:
- image: cimg/go:1.16
- image: cimg/go:1.19
steps:
- golintci-lint
- teleirc-test
go_1-17:
go_1-20:
docker:
- image: cimg/go:1.17
- image: cimg/go:1.20
steps:
- golintci-lint
- run:
Expand All @@ -64,6 +65,30 @@ jobs:
command: |
sed -i 's/github.com\/ritlug\/teleirc\///g' c.out
/tmp/cc-test-reporter after-build
go_1-25:
docker:
- image: cimg/go:1.25
steps:
- checkout
- run:
name: Download and install golintci-lint.
command: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sudo sh -s -- -b $(go env GOPATH)/bin v2.6.1
- run:
name: Run Go linter checks.
command: golangci-lint run
- teleirc-test
- run:
name: Display test coverage summary.
command: |
go tool cover -func=c.out
echo "Total coverage:"
go tool cover -func=c.out | grep total | awk '{print $3}'
- run:
name: Generate HTML coverage report.
command: go tool cover -html=c.out -o coverage.html
- store_artifacts:
path: coverage.html
destination: coverage-report
build_docs:
docker:
- image: cimg/python:3.10
Expand Down
56 changes: 27 additions & 29 deletions .github/workflows/publish_docker_image.yml
Original file line number Diff line number Diff line change
@@ -1,49 +1,47 @@
name: Build and Push Docker Image

name: Build and Publish Docker Image

#on:
# push:
# branches:
# - main
# tags:
# - 'v*'
on:
pull_request:
branches:
- main
push:
branches: [main]

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

concurrency:
group: teleirc-docker-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
tags:
- 'v*'

jobs:
build-and-push-image:
name: Build and Push Image

build-and-push:
name: Build and Push Docker Image to GHCR
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write

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

- name: Log in to the Container registry
uses: docker/login-action@v2
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Set up docker buildx
uses: docker/setup-buildx-action@v3

- name: Build and push Docker image
uses: docker/build-push-action@v4
- name: Build and push docker image
uses: docker/build-push-action@v6
with:
push: true
context: .
file: ./deployments/container/Dockerfile
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
push: true
tags: |
ghcr.io/ritlug/${{ github.repository##*/ }}:${{ github.sha }}
16 changes: 13 additions & 3 deletions cmd/teleirc.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"os/signal"
"syscall"
"strconv"

tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
"github.com/ritlug/teleirc/internal"
Expand All @@ -15,7 +16,9 @@ import (

var (
flagPath = flag.String("conf", ".env", "config file")
flagDebug = flag.Bool("debug", false, "enable debugging output")
flagDebug = flag.Bool("debug", func() bool { env, _ := strconv.ParseBool(os.Getenv("DEBUG")); return env }(), "enable debugging output")
flagMuteIrc = flag.Bool("muteirc", func() bool { env, _ := strconv.ParseBool(os.Getenv("DISABLE_RELAY_TO_IRC")); return env }(), "disable Telegram messages to IRC")
flagMuteTg = flag.Bool("mutetelegram", func() bool { env, _ := strconv.ParseBool(os.Getenv("DISABLE_RELAY_TO_TELEGRAM")); return env }(), "disable IRC messages to Telegram")
flagVersion = flag.Bool("version", false, "displays current version of TeleIRC")
version string
)
Expand All @@ -33,6 +36,13 @@ func main() {
// Notify that logger is enabled
logger.LogDebug("Debug mode enabled!")

if *flagMuteIrc {
logger.LogInfo("Relaying messages to IRC is turned OFF!")
}
if *flagMuteTg {
logger.LogInfo("Relaying messages to Telegram is turned OFF!")
}

settings, err := internal.LoadConfig(*flagPath)
if err != nil {
logger.LogError(err)
Expand All @@ -43,10 +53,10 @@ func main() {
signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM)

var tgapi *tgbotapi.BotAPI
tgClient := tg.NewClient(&settings.Telegram, &settings.IRC, &settings.Imgur, tgapi, logger)
tgClient := tg.NewClient(&settings.Telegram, &settings.IRC, &settings.Imgur, tgapi, logger, *flagMuteIrc)
tgChan := make(chan error)

ircClient := irc.NewClient(&settings.IRC, &settings.Telegram, logger)
ircClient := irc.NewClient(&settings.IRC, &settings.Telegram, logger, *flagMuteTg)
ircChan := make(chan error)

go ircClient.StartBot(ircChan, tgClient.SendMessage)
Expand Down
4 changes: 1 addition & 3 deletions deployments/container/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.22-alpine AS builder
FROM golang:1.25-alpine AS builder

WORKDIR /app

Expand All @@ -16,8 +16,6 @@ RUN adduser -D teleirc-user
USER teleirc-user

COPY --from=builder /app/teleirc /opt/teleirc/teleirc
COPY --from=builder /app/.env /opt/teleirc/conf

WORKDIR /opt/teleirc
ENTRYPOINT [ "./teleirc" ]
CMD [ "-conf", "/opt/teleirc/conf", "-debug", "true" ]
5 changes: 2 additions & 3 deletions deployments/container/docker-compose.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ version: '3'
services:
teleirc:
build:
context: ../../
dockerfile: ./deployments/container/Dockerfile
env_file: ../../.env
context: https://github.com/RITlug/teleirc.git
dockerfile: deployments/container/Dockerfile
user: teleirc
23 changes: 21 additions & 2 deletions docs/user/config-file-glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,27 @@ Config file glossary
####################

This page is a glossary of different settings in the ``env.example`` configuration file.
All values shown are the default settings.
This glossary is intended for advanced users.

.. note::
All values shown are the default settings.
This glossary is intended for advanced users.


************
General settings
************

Configuration settings
========================

``DEBUG=false``
(Optional) Verbose logging, enabled when set to `true`

``DISABLE_RELAY_TO_IRC=false``
(Optional) Fully disables bridging messages from Telegram → IRC when set to `true`

``DISABLE_RELAY_TO_TELEGRAM=false``
(Optional) Fully disables bridging messages from IRC → Telegram when set to `true`


************
Expand Down
28 changes: 24 additions & 4 deletions docs/user/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,35 @@ There are two ways to deploy TeleIRC persistently:
Containers are the easiest way to deploy TeleIRC.
Dockerfiles and other deployment resources are available in ``deployments/``.

#### Build TeleIRC
Ensure you have [docker](https://www.docker.com/) installed.

#### Build TeleIRC docker image

1. Ensure you have [docker](https://www.docker.com/) installed
1. Enter container deployment directory (`cd deployments/container`)
1. Build image (`./build_image.sh`)
1. Run container (`docker run teleirc:latest`)

**NOTE**:
**This deployment method assumes you have a complete .env file**
> [!NOTE]
> This deployment can optionally copy a standalone .env file


#### Run TeleIRC using Docker compose

1. Enter container deployment directory (`cd deployments/container`)
1. Run service using `docker compose`:

```bash
IRC_SERVER=chat.freenode.net \
IRC_CHANNEL='#channelname' \
IRC_BOT_NAME='teleirc' \
TELEIRC_TOKEN='000000000:AAAAAAaAAa2AaAAaoAAAA-a_aaAAaAaaaAA' \
TELEGRAM_CHAT_ID='-0000000000000' \
docker compose up -d teleirc
```

> [!TIP]
> Instead you can also add `environment:` entries via `docker-compose.yml`, or pass a standalone `.env` file using the CLI:
> `docker compose --env-file ../../.env up --build -d teleirc`


### Run binary
Expand Down
14 changes: 14 additions & 0 deletions env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@
# See the Config File Glossary for instructions.
# https://docs.teleirc.com/en/latest/user/config-file-glossary/

###############################################################################
# #
# General settings #
# #
###############################################################################

#####----- Configuration settings -----#####
DEBUG=false
DISABLE_RELAY_TO_IRC=false
DISABLE_RELAY_TO_TELEGRAM=false



###############################################################################
# #
# IRC configuration settings #
Expand Down Expand Up @@ -77,6 +90,7 @@ LEAVE_MESSAGE_ALLOW_LIST=""
SHOW_DISCONNECT_MESSAGE=true



################################################################################
# #
# Imgur configuration settings #
Expand Down
31 changes: 26 additions & 5 deletions internal/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package internal
import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/caarlos0/env/v6"
Expand Down Expand Up @@ -135,13 +136,33 @@ func LoadConfig(path string) (*Settings, error) {
if err := validate.RegisterValidation("notempty", validateEmptyString); err != nil {
return nil, err
}
// Attempt to load environment variables from path if path was provided
if path != ".env" && path != "" {
if err := godotenv.Load(path); err != nil {
return nil, err
// If a path was provided, try to load it.
if path != "" {
if info, err := os.Stat(path); err == nil {
// If the path is a directory, look for <path>/.env.
if info.IsDir() {
envFile := filepath.Join(path, defaultPath)
if _, err := os.Stat(envFile); err == nil {
if err := godotenv.Load(envFile); err != nil {
return nil, err
}
}
} else {
// path exists and is a file — attempt to load it
if err := godotenv.Load(path); err != nil {
return nil, err
}
}
} else {
// If the provided path does not exist, continue and rely on passed process ENV variables
if os.IsNotExist(err) {
warning.Printf("config path %q not provided or does not exist; continuing and using process environment variables", path)
} else {
return nil, err
}
}
} else if _, err := os.Stat(defaultPath); !os.IsNotExist(err) {
// Attempt to load from defaultPath if defaultPath exists
// Attempt to load from defaultPath if it exists
if err := godotenv.Load(defaultPath); err != nil {
return nil, err
}
Expand Down
Loading