fix(ads): add gitlab ci

add gitlab ci
This commit is contained in:
Haydar Ghasemi 2026-09-20 15:43:49 +03:30
parent 3e81a0a0f1
commit 6e7c9b9978
6 changed files with 146 additions and 93 deletions

18
.dockerignore Normal file
View file

@ -0,0 +1,18 @@
.git
.idea
.claude
.forgejo
.gitlab-ci.yml
.env
.env.*
*.env
delme*.py
venv
.venv
__pycache__
*.pyc
.pytest_cache
log
logs
media
advertising_db

3
.gitignore vendored
View file

@ -1,8 +1,11 @@
.idea .idea
.env .env
local.env
staging.env
media media
/clients/ /clients/
/delme.py /delme.py
/delme_not_commit.py
/log/accounts.log /log/accounts.log
/log/errors.log /log/errors.log
**/__pycache__ **/__pycache__

104
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,104 @@
stages:
- build
- test
- deploy
# The container registry (port 5050) is not reachable from the runners, so
# nothing is pushed. Once it is, add a job that pushes $CI_REGISTRY_IMAGE.
# Checks that the Dockerfile builds. Uses the runner host's Docker daemon, so
# the runner needs /var/run/docker.sock in [runners.docker] volumes (no dind).
build:
stage: build
image: docker:27
tags:
- local
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
- docker build --pull -t chat-ci:$CI_JOB_ID .
after_script:
- docker rmi chat-ci:$CI_JOB_ID || true
test:
stage: test
image: debian:13
tags:
- local
services:
# no PostGIS needed: the settings use the plain postgresql backend
- name: postgres:17
alias: chat_db
- name: redis:7
alias: redis
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
cache:
key: pip
paths:
- .cache/pip
variables:
PIP_CACHE_DIR: $CI_PROJECT_DIR/.cache/pip
# postgres service
POSTGRES_USER: ci
POSTGRES_PASSWORD: ci-password
POSTGRES_DB: chat_db
# app settings; dummy values only, real secrets never belong in a test job
DEBUG: "true"
DB_NAME: chat_db
DB_USER: ci
DB_PASSWORD: ci-password
DB_HOST: chat_db
DB_PORT: "5432"
REDIS_BASE_URL: redis://redis:6379/1
ACCOUNTS_BASE_PUBLIC_URL: https://accounts.invalid
OAUTH2_PROVIDER_BASE_PUBLIC_URL: https://accounts.invalid/oauth2
OAUTH2_PROVIDER_BASE_PRIVATE_URL: https://accounts.invalid/oauth2
OAUTH2_PROVIDER_CLIENT_ID: ci
OAUTH2_PROVIDER_CLIENT_SECRET: ci
MINIO_ENDPOINT: minio.invalid
MINIO_ACCESS_KEY: ci
MINIO_SECRET_KEY: ci
before_script:
# keep in sync with the Dockerfile
- apt-get update
- apt-get install -y python3 python3-pip binutils libproj-dev gdal-bin
- pip3 install --break-system-packages --ignore-installed -r requirements.txt
- pip3 install --break-system-packages setuptools
script:
- python3 manage.py check
- python3 manage.py makemigrations --check --dry-run
# the suite is pytest-style; `manage.py test` would silently run 0 tests
- python3 -m pytest -q --junitxml=report.xml
artifacts:
when: always
reports:
junit: report.xml
# Runs on the staging host through a shell runner tagged `staging` that can use
# the docker CLI. The compose stack keeps a git checkout of this repo (mounted
# at /app), so this updates that checkout and restarts the service.
# Set DEPLOY_DIR in Settings > CI/CD > Variables (the directory that holds
# docker-compose.yml). DEPLOY_CHECKOUT and DEPLOY_SERVICE default to `chat`;
# override them there if the checkout directory or compose service is named
# differently.
deploy_staging:
stage: deploy
tags:
- staging
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: manual
allow_failure: true # otherwise the pipeline shows "blocked" until someone deploys
resource_group: staging # never run two deploys at once
environment:
name: staging
variables:
DEPLOY_CHECKOUT: chat
DEPLOY_SERVICE: chat
script:
- cd "${DEPLOY_DIR:?set DEPLOY_DIR in Settings > CI/CD > Variables}"
- git -C "$DEPLOY_CHECKOUT" pull --ff-only origin "$CI_DEFAULT_BRANCH"
- docker compose up -d --build "$DEPLOY_SERVICE"

View file

@ -1,11 +1,15 @@
FROM base:debian_13 FROM debian:13
ENV PYTHONUNBUFFERED 1 ENV PYTHONUNBUFFERED=1
WORKDIR /app WORKDIR /app
#RUN date
RUN apt update # netcat-openbsd: run.sh waits for the DB with `nc -z`
#RUN apt install gnupg2 netcat-traditional libssl-dev libcrypto++-dev lsb-release python3-pip -y RUN apt-get update && \
#RUN apt install binutils libproj-dev gdal-bin -y apt-get install -y python3 python3-pip binutils libproj-dev gdal-bin netcat-openbsd && \
RUN apt install nano htop iputils-ping -y rm -rf /var/lib/apt/lists/*
#COPY requirements.txt /app/requirements.txt COPY requirements.txt /app/requirements.txt
#RUN pip3 install --break-system-packages -r requirements.txt RUN pip3 install --break-system-packages --ignore-installed -r requirements.txt
RUN pip3 install --break-system-packages setuptools
# In docker compose the checkout mounted at /app overrides this copy;
# in CI the image has to carry the code itself.
COPY . /app
#ENTRYPOINT ["./run.sh"] #ENTRYPOINT ["./run.sh"]

View file

@ -1,3 +1,5 @@
import os
import pytest import pytest
@ -6,6 +8,8 @@ def django_db_setup(django_test_environment, django_db_blocker):
""" """
Override pytest-django's default DB setup to: Override pytest-django's default DB setup to:
- Use the local unix-socket superuser instead of the .env credentials - Use the local unix-socket superuser instead of the .env credentials
(skipped in CI, where the DB service credentials come from the
environment)
- Remove psycopg3 connection pooling (pool=True conflicts with test - Remove psycopg3 connection pooling (pool=True conflicts with test
transaction wrapping and causes PoolTimeout during test-DB creation) transaction wrapping and causes PoolTimeout during test-DB creation)
""" """
@ -13,6 +17,7 @@ def django_db_setup(django_test_environment, django_db_blocker):
from django.test.utils import setup_databases from django.test.utils import setup_databases
db = settings.DATABASES["default"] db = settings.DATABASES["default"]
if not os.environ.get("CI"):
db["USER"] = "hashdal" db["USER"] = "hashdal"
db["PASSWORD"] = "" db["PASSWORD"] = ""
db["HOST"] = "" db["HOST"] = ""

View file

@ -1,81 +0,0 @@
from mattermostdriver import Driver
from django.conf import settings
from pprint import pprint
mattermost = Driver({
'url': 'chat.addwin.ir',
# 'login_id': 'sahama',
# 'password': settings.MATTERMOST_BASE_PUBLICE_URL,
# 'token': settings.MATTERMOST_TOKEN,
'token': 'x36shfdd5fnz3qm9ut7crb6xoh',
'scheme': 'https',
'port': 443,
'basepath': '/api/v4',
'verify': True, # Or /path/to/file.pem
# 'mfa_token': 'YourMFAToken',
'auth': None,
'timeout': 30,
'request_timeout': None,
'keepalive': False,
'keepalive_delay': 5,
'websocket_kw_args': None,
'debug': True
})
# mattermost.login()
# mattermost.users.create_user(options={
# "email": "user2@example.com",
# "username": "newuser2",
# "first_name": "John",
# "last_name": "Doe",
# "password": "SecurePassword123!",}
# )
user_client = Driver({
'url': 'chat.addwin.ir',
'login_id': 'newuser',
'password': 'SecurePassword123!',
# 'token': settings.MATTERMOST_TOKEN,
'scheme': 'https',
'port': 443,
'basepath': '/api/v4',
'verify': True, # Or /path/to/file.pem
# 'mfa_token': 'YourMFAToken',
'auth': None,
'timeout': 30,
'request_timeout': None,
'keepalive': False,
'keepalive_delay': 5,
'websocket_kw_args': None,
'debug': True
})
user_client.login()
# print(user_client.users.get_user_by_username(username='newuser')) # jrrryzhq4bfftchoe1anji6a5c
# print(user_client.users.get_user_by_username(username='newuser2')) # yy6ew7jy63dnb85ox6skgi969r
# print(user_client.users.get_user_by_username(username='sahama')) # hqst9xib4typ7fynq3wn4qnzye
# print(user_client.users.get_user_by_username(username='ghasemi')) # w6ou8xyaqiyw5b8e3bhyae17xw
print(user_client.channels.create_direct_message_channel(options=["jrrryzhq4bfftchoe1anji6a5c", "w6ou8xyaqiyw5b8e3bhyae17xw"]))
# exit()
print(user_client.posts.create_post(options={
"channel_id": "76xjniwh3jgdtmitk66nigtktr", # anth9sme4bn9tdantqxx1g4kky
"message": "پیام از سمت پایتون"
}))
pprint(user_client.posts.get_unread_posts_for_channel(**{
"channel_id": "anth9sme4bn9tdantqxx1g4kky",
"user_id": "jrrryzhq4bfftchoe1anji6a5c"
}))