Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77d1585ed5 | ||
|
|
e03eae219d | ||
|
|
35bb116bfd | ||
|
|
012d81bd66 | ||
|
|
5531a42ed7 | ||
|
|
36e574ed3a | ||
|
|
7172fe3659 | ||
|
|
9a7de46061 | ||
|
|
97798df417 | ||
|
|
029319e7c1 | ||
|
|
b8ba3df310 | ||
|
|
e196a79174 | ||
|
|
5407479361 | ||
|
|
af5d46e4e8 | ||
|
|
718a4ff1c9 | ||
|
|
5e6d3e968d | ||
|
|
82ade98af3 | ||
|
|
1be50c3eeb | ||
|
|
8a3c6b50e3 |
66
.drone.yml
66
.drone.yml
@ -53,7 +53,8 @@ steps:
|
|||||||
path: /root/.nuget/packages
|
path: /root/.nuget/packages
|
||||||
commands:
|
commands:
|
||||||
- cd flea
|
- cd flea
|
||||||
- dotnet nuget add source --name musk https://gitea.musk.fun/api/packages/nocr/nuget/index.json
|
- mkdir -p /root/.nuget/NuGet
|
||||||
|
- cp nuget.config /root/.nuget/NuGet/NuGet.Config
|
||||||
- echo "🔄 Restoring all projects..."
|
- echo "🔄 Restoring all projects..."
|
||||||
- dotnet restore telegram-listener/Nocr.TelegramListener.sln
|
- dotnet restore telegram-listener/Nocr.TelegramListener.sln
|
||||||
- dotnet restore telegram-client/Nocr.TelegramClient.sln
|
- dotnet restore telegram-client/Nocr.TelegramClient.sln
|
||||||
@ -147,7 +148,8 @@ steps:
|
|||||||
path: /root/.nuget/packages
|
path: /root/.nuget/packages
|
||||||
commands:
|
commands:
|
||||||
- cd flea
|
- cd flea
|
||||||
- dotnet nuget add source --name musk https://gitea.musk.fun/api/packages/nocr/nuget/index.json
|
- mkdir -p /root/.nuget/NuGet
|
||||||
|
- cp nuget.config /root/.nuget/NuGet/NuGet.Config
|
||||||
- dotnet restore telegram-listener/Nocr.TelegramListener.sln
|
- dotnet restore telegram-listener/Nocr.TelegramListener.sln
|
||||||
- dotnet restore telegram-client/Nocr.TelegramClient.sln
|
- dotnet restore telegram-client/Nocr.TelegramClient.sln
|
||||||
- dotnet restore text-matcher/Nocr.TextMatcher.sln
|
- dotnet restore text-matcher/Nocr.TextMatcher.sln
|
||||||
@ -250,7 +252,8 @@ steps:
|
|||||||
COMMIT_MSG=$(git log -1 --pretty=%B)
|
COMMIT_MSG=$(git log -1 --pretty=%B)
|
||||||
if echo "$COMMIT_MSG" | grep -q "contracts_only:telegram_listener"; then
|
if echo "$COMMIT_MSG" | grep -q "contracts_only:telegram_listener"; then
|
||||||
echo "📦 Publishing telegram-listener contracts..."
|
echo "📦 Publishing telegram-listener contracts..."
|
||||||
dotnet nuget add source --name musk https://gitea.musk.fun/api/packages/nocr/nuget/index.json
|
mkdir -p /root/.nuget/NuGet
|
||||||
|
cp nuget.config /root/.nuget/NuGet/NuGet.Config
|
||||||
dotnet pack telegram-listener/Nocr.TelegramListener.sln -o ./bin -p:PackageVersion=${DRONE_TAG}
|
dotnet pack telegram-listener/Nocr.TelegramListener.sln -o ./bin -p:PackageVersion=${DRONE_TAG}
|
||||||
dotnet nuget push ./bin/*Contract*.nupkg --api-key $NUGETAPIKEY --source musk --skip-duplicate
|
dotnet nuget push ./bin/*Contract*.nupkg --api-key $NUGETAPIKEY --source musk --skip-duplicate
|
||||||
else
|
else
|
||||||
@ -273,7 +276,8 @@ steps:
|
|||||||
COMMIT_MSG=$(git log -1 --pretty=%B)
|
COMMIT_MSG=$(git log -1 --pretty=%B)
|
||||||
if echo "$COMMIT_MSG" | grep -q "contracts_only:text_matcher"; then
|
if echo "$COMMIT_MSG" | grep -q "contracts_only:text_matcher"; then
|
||||||
echo "📦 Publishing text-matcher contracts..."
|
echo "📦 Publishing text-matcher contracts..."
|
||||||
dotnet nuget add source --name musk https://gitea.musk.fun/api/packages/nocr/nuget/index.json
|
mkdir -p /root/.nuget/NuGet
|
||||||
|
cp nuget.config /root/.nuget/NuGet/NuGet.Config
|
||||||
dotnet pack text-matcher/Nocr.TextMatcher.sln -o ./bin -p:PackageVersion=${DRONE_TAG}
|
dotnet pack text-matcher/Nocr.TextMatcher.sln -o ./bin -p:PackageVersion=${DRONE_TAG}
|
||||||
dotnet nuget push ./bin/*Contract*.nupkg --api-key $NUGETAPIKEY --source musk --skip-duplicate
|
dotnet nuget push ./bin/*Contract*.nupkg --api-key $NUGETAPIKEY --source musk --skip-duplicate
|
||||||
else
|
else
|
||||||
@ -296,7 +300,8 @@ steps:
|
|||||||
COMMIT_MSG=$(git log -1 --pretty=%B)
|
COMMIT_MSG=$(git log -1 --pretty=%B)
|
||||||
if echo "$COMMIT_MSG" | grep -q "contracts_only:users"; then
|
if echo "$COMMIT_MSG" | grep -q "contracts_only:users"; then
|
||||||
echo "📦 Publishing users contracts..."
|
echo "📦 Publishing users contracts..."
|
||||||
dotnet nuget add source --name musk https://gitea.musk.fun/api/packages/nocr/nuget/index.json
|
mkdir -p /root/.nuget/NuGet
|
||||||
|
cp nuget.config /root/.nuget/NuGet/NuGet.Config
|
||||||
dotnet pack users/Nocr.Users.sln -o ./bin -p:PackageVersion=${DRONE_TAG}
|
dotnet pack users/Nocr.Users.sln -o ./bin -p:PackageVersion=${DRONE_TAG}
|
||||||
dotnet nuget push ./bin/*Contract*.nupkg --api-key $NUGETAPIKEY --source musk --skip-duplicate
|
dotnet nuget push ./bin/*Contract*.nupkg --api-key $NUGETAPIKEY --source musk --skip-duplicate
|
||||||
else
|
else
|
||||||
@ -371,7 +376,8 @@ steps:
|
|||||||
from_secret: nuget_musk_api_key
|
from_secret: nuget_musk_api_key
|
||||||
commands:
|
commands:
|
||||||
- cd flea
|
- cd flea
|
||||||
- dotnet nuget add source --name musk https://gitea.musk.fun/api/packages/nocr/nuget/index.json
|
- mkdir -p /root/.nuget/NuGet
|
||||||
|
- cp nuget.config /root/.nuget/NuGet/NuGet.Config
|
||||||
- dotnet pack telegram-listener/Nocr.TelegramListener.sln -o ./bin -p:PackageVersion=${DRONE_TAG}
|
- dotnet pack telegram-listener/Nocr.TelegramListener.sln -o ./bin -p:PackageVersion=${DRONE_TAG}
|
||||||
- dotnet nuget push ./bin/*Contract*.nupkg --api-key $NUGETAPIKEY --source musk --skip-duplicate
|
- dotnet nuget push ./bin/*Contract*.nupkg --api-key $NUGETAPIKEY --source musk --skip-duplicate
|
||||||
depends_on:
|
depends_on:
|
||||||
@ -387,7 +393,8 @@ steps:
|
|||||||
from_secret: nuget_musk_api_key
|
from_secret: nuget_musk_api_key
|
||||||
commands:
|
commands:
|
||||||
- cd flea
|
- cd flea
|
||||||
- dotnet nuget add source --name musk https://gitea.musk.fun/api/packages/nocr/nuget/index.json
|
- mkdir -p /root/.nuget/NuGet
|
||||||
|
- cp nuget.config /root/.nuget/NuGet/NuGet.Config
|
||||||
- dotnet pack text-matcher/Nocr.TextMatcher.sln -o ./bin -p:PackageVersion=${DRONE_TAG}
|
- dotnet pack text-matcher/Nocr.TextMatcher.sln -o ./bin -p:PackageVersion=${DRONE_TAG}
|
||||||
- dotnet nuget push ./bin/*Contract*.nupkg --api-key $NUGETAPIKEY --source musk --skip-duplicate
|
- dotnet nuget push ./bin/*Contract*.nupkg --api-key $NUGETAPIKEY --source musk --skip-duplicate
|
||||||
depends_on:
|
depends_on:
|
||||||
@ -404,7 +411,8 @@ steps:
|
|||||||
from_secret: nuget_musk_api_key
|
from_secret: nuget_musk_api_key
|
||||||
commands:
|
commands:
|
||||||
- cd flea
|
- cd flea
|
||||||
- dotnet nuget add source --name musk https://gitea.musk.fun/api/packages/nocr/nuget/index.json
|
- mkdir -p /root/.nuget/NuGet
|
||||||
|
- cp nuget.config /root/.nuget/NuGet/NuGet.Config
|
||||||
- dotnet pack users/Nocr.Users.sln -o ./bin -p:PackageVersion=${DRONE_TAG}
|
- dotnet pack users/Nocr.Users.sln -o ./bin -p:PackageVersion=${DRONE_TAG}
|
||||||
- dotnet nuget push ./bin/*Contract*.nupkg --api-key $NUGETAPIKEY --source musk --skip-duplicate
|
- dotnet nuget push ./bin/*Contract*.nupkg --api-key $NUGETAPIKEY --source musk --skip-duplicate
|
||||||
depends_on:
|
depends_on:
|
||||||
@ -425,7 +433,9 @@ steps:
|
|||||||
commands:
|
commands:
|
||||||
- mkdir -p /kaniko/.docker
|
- mkdir -p /kaniko/.docker
|
||||||
- echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json
|
- echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json
|
||||||
- cd flea/telegram-listener
|
- cd flea
|
||||||
|
- cp nuget.config telegram-listener/
|
||||||
|
- cd telegram-listener
|
||||||
- |
|
- |
|
||||||
/kaniko/executor \
|
/kaniko/executor \
|
||||||
--context=. \
|
--context=. \
|
||||||
@ -449,7 +459,9 @@ steps:
|
|||||||
commands:
|
commands:
|
||||||
- mkdir -p /kaniko/.docker
|
- mkdir -p /kaniko/.docker
|
||||||
- echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json
|
- echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json
|
||||||
- cd flea/telegram-client
|
- cd flea
|
||||||
|
- cp nuget.config telegram-client/
|
||||||
|
- cd telegram-client
|
||||||
- |
|
- |
|
||||||
/kaniko/executor \
|
/kaniko/executor \
|
||||||
--context=. \
|
--context=. \
|
||||||
@ -473,7 +485,9 @@ steps:
|
|||||||
commands:
|
commands:
|
||||||
- mkdir -p /kaniko/.docker
|
- mkdir -p /kaniko/.docker
|
||||||
- echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json
|
- echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json
|
||||||
- cd flea/text-matcher
|
- cd flea
|
||||||
|
- cp nuget.config text-matcher/
|
||||||
|
- cd text-matcher
|
||||||
- |
|
- |
|
||||||
/kaniko/executor \
|
/kaniko/executor \
|
||||||
--context=. \
|
--context=. \
|
||||||
@ -497,7 +511,9 @@ steps:
|
|||||||
commands:
|
commands:
|
||||||
- mkdir -p /kaniko/.docker
|
- mkdir -p /kaniko/.docker
|
||||||
- echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json
|
- echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json
|
||||||
- cd flea/text-matcher
|
- cd flea
|
||||||
|
- cp nuget.config text-matcher/
|
||||||
|
- cd text-matcher
|
||||||
- |
|
- |
|
||||||
/kaniko/executor \
|
/kaniko/executor \
|
||||||
--context=. \
|
--context=. \
|
||||||
@ -521,7 +537,9 @@ steps:
|
|||||||
commands:
|
commands:
|
||||||
- mkdir -p /kaniko/.docker
|
- mkdir -p /kaniko/.docker
|
||||||
- echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json
|
- echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json
|
||||||
- cd flea/users
|
- cd flea
|
||||||
|
- cp nuget.config users/
|
||||||
|
- cd users
|
||||||
- |
|
- |
|
||||||
/kaniko/executor \
|
/kaniko/executor \
|
||||||
--context=. \
|
--context=. \
|
||||||
@ -545,7 +563,9 @@ steps:
|
|||||||
commands:
|
commands:
|
||||||
- mkdir -p /kaniko/.docker
|
- mkdir -p /kaniko/.docker
|
||||||
- echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json
|
- echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json
|
||||||
- cd flea/users
|
- cd flea
|
||||||
|
- cp nuget.config users/
|
||||||
|
- cd users
|
||||||
- |
|
- |
|
||||||
/kaniko/executor \
|
/kaniko/executor \
|
||||||
--context=. \
|
--context=. \
|
||||||
@ -565,10 +585,15 @@ steps:
|
|||||||
|
|
||||||
- name: deploy-to-k8s
|
- name: deploy-to-k8s
|
||||||
image: bitnami/kubectl:latest
|
image: bitnami/kubectl:latest
|
||||||
|
environment:
|
||||||
|
KUBECONFIG_CONTENT:
|
||||||
|
from_secret: kubeconfig
|
||||||
commands:
|
commands:
|
||||||
|
- mkdir -p $HOME/.kube
|
||||||
|
- echo "$KUBECONFIG_CONTENT" > $HOME/.kube/config
|
||||||
|
- chmod 600 $HOME/.kube/config
|
||||||
- cd flea/_deploy/scripts
|
- cd flea/_deploy/scripts
|
||||||
- chmod +x deploy.sh
|
- sh deploy.sh "${DRONE_TAG}" "${DRONE_COMMIT_SHA:0:7}"
|
||||||
- ./deploy.sh "${DRONE_TAG}" "${DRONE_COMMIT_SHA:0:7}"
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- users-migrator-build-push
|
- users-migrator-build-push
|
||||||
when:
|
when:
|
||||||
@ -625,9 +650,14 @@ steps:
|
|||||||
|
|
||||||
- name: deploy
|
- name: deploy
|
||||||
image: bitnami/kubectl:latest
|
image: bitnami/kubectl:latest
|
||||||
|
environment:
|
||||||
|
KUBECONFIG_CONTENT:
|
||||||
|
from_secret: kubeconfig
|
||||||
commands:
|
commands:
|
||||||
|
- mkdir -p $HOME/.kube
|
||||||
|
- echo "$KUBECONFIG_CONTENT" > $HOME/.kube/config
|
||||||
|
- chmod 600 $HOME/.kube/config
|
||||||
- cd flea/_deploy/scripts
|
- cd flea/_deploy/scripts
|
||||||
- chmod +x deploy.sh
|
- sh deploy.sh "${DRONE_TAG}" "" "latest"
|
||||||
- ./deploy.sh "${DRONE_TAG}" "${DRONE_COMMIT_SHA:0:7}"
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- check-trigger
|
- check-trigger
|
||||||
|
|||||||
433
CLAUDE.md
433
CLAUDE.md
@ -27,28 +27,39 @@ The services follow a message bus pattern using RabbitMQ for async communication
|
|||||||
**Note:** WTelegram sends both `UpdateNewChannelMessage` and `UpdateEditChannelMessage` for the same message. TelegramListener publishes separate events to avoid duplicate notifications downstream.
|
**Note:** WTelegram sends both `UpdateNewChannelMessage` and `UpdateEditChannelMessage` for the same message. TelegramListener publishes separate events to avoid duplicate notifications downstream.
|
||||||
|
|
||||||
Each service follows Clean Architecture with separate projects for:
|
Each service follows Clean Architecture with separate projects for:
|
||||||
- Host (API/entry point)
|
- **Host** (API/entry point) - ASP.NET Core application, controllers, startup configuration
|
||||||
- AppServices (business logic)
|
- **AppServices** (business logic) - Use cases, business logic, command/query handlers
|
||||||
- Core (shared utilities)
|
- **Core** (shared utilities) - Domain entities, interfaces, shared logic
|
||||||
- Api.Contracts (REST API contracts)
|
- **Api.Contracts** (REST API contracts) - DTOs, request/response models for REST endpoints (published as NuGet)
|
||||||
- Async.Api.Contracts (event contracts)
|
- **Async.Api.Contracts** (event contracts) - Event DTOs for RabbitMQ messaging (published as NuGet)
|
||||||
- Persistence (database layer, where applicable)
|
- **Persistence** (database layer) - EF Core DbContext, repositories, data access (text-matcher, users only)
|
||||||
- Migrator (database migrations, where applicable)
|
- **Migrator** (database migrations) - EF Core migrations, migration scripts (text-matcher, users only)
|
||||||
|
|
||||||
|
**Project Structure Examples:**
|
||||||
|
- telegram-listener: Host, AppServices, Core, Async.Api.Contracts (no database)
|
||||||
|
- telegram-client: Host, AppServices, Core (no database, no published contracts)
|
||||||
|
- text-matcher: Host, AppServices, Core, Api.Contracts, Async.Api.Contracts, Persistence, Migrator
|
||||||
|
- users: Host, AppServices, Core, Api.Contracts, Persistence, Migrator
|
||||||
|
|
||||||
## Development Commands
|
## Development Commands
|
||||||
|
|
||||||
### Running the System
|
### Running the System
|
||||||
```bash
|
```bash
|
||||||
|
# IMPORTANT: Before building with Docker Compose, prepare the build environment
|
||||||
|
./prepare-build.sh
|
||||||
|
|
||||||
# Start all services with Docker Compose
|
# Start all services with Docker Compose
|
||||||
docker-compose up
|
docker-compose up
|
||||||
|
|
||||||
# Start individual services for development
|
# Start individual services for development (no preparation needed)
|
||||||
cd telegram-client && dotnet run --project src/Nocr.TelegramClient.Host
|
cd telegram-client && dotnet run --project src/Nocr.TelegramClient.Host
|
||||||
cd telegram-listener && dotnet run --project src/Nocr.TelegramListener.Host
|
cd telegram-listener && dotnet run --project src/Nocr.TelegramListener.Host
|
||||||
cd text-matcher && dotnet run --project src/Nocr.TextMatcher.Host
|
cd text-matcher && dotnet run --project src/Nocr.TextMatcher.Host
|
||||||
cd users && dotnet run --project src/Nocr.Users.Host
|
cd users && dotnet run --project src/Nocr.Users.Host
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Note:** The `prepare-build.sh` script copies `nuget.config` to all submodule roots, which is required for Docker builds. This step is automatic in CI/CD but must be run manually for local Docker Compose builds.
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
```bash
|
```bash
|
||||||
# Build individual services
|
# Build individual services
|
||||||
@ -60,8 +71,17 @@ dotnet build src/Nocr.<ServiceName>.Host
|
|||||||
|
|
||||||
### Testing
|
### Testing
|
||||||
```bash
|
```bash
|
||||||
# Run unit tests (only text-matcher has tests currently)
|
# Run all tests in text-matcher
|
||||||
cd text-matcher && dotnet test
|
cd text-matcher && dotnet test
|
||||||
|
|
||||||
|
# Run tests for a specific project
|
||||||
|
cd text-matcher && dotnet test tests/Nocr.TextMatcher.AppServices.UnitTests/Nocr.TextMatcher.AppServices.UnitTests.csproj
|
||||||
|
|
||||||
|
# Run tests with verbose output
|
||||||
|
cd text-matcher && dotnet test --verbosity detailed
|
||||||
|
|
||||||
|
# Run tests with code coverage (if configured)
|
||||||
|
cd text-matcher && dotnet test --collect:"XPlat Code Coverage"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Database Migrations
|
### Database Migrations
|
||||||
@ -75,6 +95,29 @@ cd users && ./src/Nocr.Users.Migrator/AddMigration.sh MyMigrationName
|
|||||||
# Apply migrations (handled automatically by migrator containers in docker-compose)
|
# Apply migrations (handled automatically by migrator containers in docker-compose)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Working with Git Submodules
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Initialize submodules after cloning the repository
|
||||||
|
git submodule update --init --recursive
|
||||||
|
|
||||||
|
# Update all submodules to their latest commits on main
|
||||||
|
./update-submodules.sh
|
||||||
|
|
||||||
|
# Commit and push changes to all submodules at once
|
||||||
|
./commit-all.sh "Your commit message"
|
||||||
|
|
||||||
|
# Update a single submodule
|
||||||
|
cd telegram-listener
|
||||||
|
git pull origin main
|
||||||
|
cd ..
|
||||||
|
git add telegram-listener
|
||||||
|
git commit -m "Update telegram-listener submodule"
|
||||||
|
|
||||||
|
# Check status of all submodules
|
||||||
|
git submodule status
|
||||||
|
```
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
**📖 See [CONFIGURATION.md](CONFIGURATION.md) for detailed configuration guide.**
|
**📖 See [CONFIGURATION.md](CONFIGURATION.md) for detailed configuration guide.**
|
||||||
@ -133,13 +176,47 @@ When running with docker-compose:
|
|||||||
|
|
||||||
## Key Technologies
|
## Key Technologies
|
||||||
|
|
||||||
- .NET 8
|
- **.NET 8** - All services built on .NET 8
|
||||||
- ASP.NET Core Web APIs
|
- **ASP.NET Core Web APIs** - REST endpoints and hosting
|
||||||
- Entity Framework Core with MariaDB
|
- **Entity Framework Core with MariaDB** - ORM for text-matcher and users databases
|
||||||
- WTelegramClient for Telegram API
|
- **WTelegramClient** - MTProto API client for telegram-listener
|
||||||
- Rebus for message bus (RabbitMQ)
|
- **Telegram.Bot** - Bot API client for telegram-client
|
||||||
- Docker & Docker Compose for containerization
|
- **Rebus** - Message bus abstraction over RabbitMQ
|
||||||
- Drone CI/CD on Kubernetes
|
- **RabbitMQ** - Message broker for async event-driven communication
|
||||||
|
- **Docker & Docker Compose** - Local development and containerization
|
||||||
|
- **Kaniko** - Container image building in CI/CD
|
||||||
|
- **Drone CI** - CI/CD pipeline on Kubernetes
|
||||||
|
|
||||||
|
## NuGet Package Management
|
||||||
|
|
||||||
|
The project uses **Central Package Management (CPM)** with **Package Source Mapping** to manage NuGet dependencies:
|
||||||
|
|
||||||
|
### Package Sources
|
||||||
|
|
||||||
|
- **nuget.org**: All public packages (Microsoft.*, Serilog.*, etc.)
|
||||||
|
- **musk** (private): Internal `Nocr.*` contract packages
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
The `nuget.config` file in the project root defines package source mapping:
|
||||||
|
```xml
|
||||||
|
<packageSourceMapping>
|
||||||
|
<packageSource key="musk">
|
||||||
|
<package pattern="Nocr.*" />
|
||||||
|
</packageSource>
|
||||||
|
<packageSource key="nuget.org">
|
||||||
|
<package pattern="*" />
|
||||||
|
</packageSource>
|
||||||
|
</packageSourceMapping>
|
||||||
|
```
|
||||||
|
|
||||||
|
### How It Works
|
||||||
|
|
||||||
|
1. **Local Development**: Copy `nuget.config` to each submodule root when needed
|
||||||
|
2. **CI/CD**: Drone automatically copies `nuget.config` to `/root/.nuget/NuGet/NuGet.Config`
|
||||||
|
3. **Docker Builds**: Kaniko copies `nuget.config` to submodule root before building
|
||||||
|
|
||||||
|
This eliminates NuGet warning NU1507 and ensures consistent package resolution across all environments.
|
||||||
|
|
||||||
## CI/CD Pipeline
|
## CI/CD Pipeline
|
||||||
|
|
||||||
@ -148,39 +225,240 @@ When running with docker-compose:
|
|||||||
The project uses Drone CI with 5 specialized pipelines:
|
The project uses Drone CI with 5 specialized pipelines:
|
||||||
|
|
||||||
### 1. Feature Validation (`feature/*`, `fix/*` branches)
|
### 1. Feature Validation (`feature/*`, `fix/*` branches)
|
||||||
- Triggered on push to feature/fix branches
|
**Purpose**: Test feature branches before merging to main
|
||||||
|
|
||||||
|
**How to trigger**:
|
||||||
|
```bash
|
||||||
|
# Create feature branch and push
|
||||||
|
git checkout -b feature/my-new-feature
|
||||||
|
# ... make changes ...
|
||||||
|
git add .
|
||||||
|
git commit -m "Add new feature"
|
||||||
|
git push origin feature/my-new-feature
|
||||||
|
```
|
||||||
|
|
||||||
|
**What happens**:
|
||||||
- Runs build + tests with Testcontainers support
|
- Runs build + tests with Testcontainers support
|
||||||
- Provides fast feedback before merge
|
- Provides fast feedback before merge
|
||||||
- Duration: ~3-5 minutes
|
- Duration: ~3-5 minutes
|
||||||
|
|
||||||
### 2. Main Validation (`main` branch)
|
### 2. Main Validation (`main` branch)
|
||||||
- Triggered on push to main
|
**Purpose**: Ensure main branch stays healthy after merge
|
||||||
|
|
||||||
|
**How to trigger**:
|
||||||
|
```bash
|
||||||
|
# Merge feature to main
|
||||||
|
git checkout main
|
||||||
|
git merge feature/my-new-feature
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
**What happens**:
|
||||||
- Same checks as feature validation
|
- Same checks as feature validation
|
||||||
- Ensures main branch stays healthy
|
- Ensures main branch builds and tests pass
|
||||||
- Duration: ~3-5 minutes
|
- Duration: ~3-5 minutes
|
||||||
|
|
||||||
### 3. Contracts-Only Publish (tags with `contracts_only:`)
|
### 3. Contracts-Only Publish
|
||||||
- Triggered by tag + commit message containing `contracts_only:<service>`
|
**Purpose**: Publish NuGet contracts without building Docker images (fast iteration)
|
||||||
- Publishes NuGet contracts without building Docker images
|
|
||||||
- Fast iteration on contract changes
|
**How to trigger**:
|
||||||
|
```bash
|
||||||
|
# Update contracts in a submodule
|
||||||
|
cd telegram-listener
|
||||||
|
# ... update Async.Api.Contracts ...
|
||||||
|
git add . && git commit -m "Add MessageEdited event"
|
||||||
|
git push
|
||||||
|
|
||||||
|
# From parent repo, tag with contracts_only marker
|
||||||
|
cd ..
|
||||||
|
git add telegram-listener
|
||||||
|
git commit -m "contracts_only:telegram_listener - Add MessageEdited event"
|
||||||
|
git tag 0.7.41
|
||||||
|
git push && git push --tags
|
||||||
|
```
|
||||||
|
|
||||||
|
**What happens**:
|
||||||
|
- Publishes only the specified service's NuGet contracts
|
||||||
|
- Skips Docker image builds
|
||||||
- Duration: ~2 minutes
|
- Duration: ~2 minutes
|
||||||
- Example: `git commit -m "contracts_only:telegram_listener - Add MessageEdited event"`
|
|
||||||
|
|
||||||
### 4. Full Release (clean tags)
|
**Services**: `telegram_listener`, `text_matcher`, `users`
|
||||||
- Triggered by tag without special markers
|
|
||||||
- Complete release cycle:
|
### 4. Full Release
|
||||||
1. Publish all NuGet contracts (parallel)
|
**Purpose**: Complete release - contracts + images + deployment
|
||||||
2. Build all Docker images with Kaniko (parallel, after contracts)
|
|
||||||
3. Deploy to Kubernetes (automatic for `v*` tags)
|
**How to trigger**:
|
||||||
|
```bash
|
||||||
|
# Make your changes, commit to main
|
||||||
|
git add .
|
||||||
|
git commit -m "Implement new feature"
|
||||||
|
git push
|
||||||
|
|
||||||
|
# Tag for full release (no special markers in commit message)
|
||||||
|
git tag v1.3.0
|
||||||
|
git push --tags
|
||||||
|
```
|
||||||
|
|
||||||
|
**What happens**:
|
||||||
|
1. Publishes all NuGet contracts (parallel)
|
||||||
|
2. Builds all Docker images with Kaniko (parallel, after contracts)
|
||||||
|
3. Deploys to Kubernetes (automatic for `v*` tags)
|
||||||
- Duration: ~8-10 minutes
|
- Duration: ~8-10 minutes
|
||||||
- Example: `git tag v1.3.0`
|
|
||||||
|
|
||||||
### 5. Deploy-Only (tags with `deploy_only:`)
|
### 5. Deploy-Only
|
||||||
- Triggered by tag + commit message containing `deploy_only:`
|
**Purpose**: Deploy existing images without rebuilding (rollbacks, hotfixes)
|
||||||
- Skips building, only deploys existing images
|
|
||||||
- Useful for rollbacks and hotfixes
|
**How to trigger**:
|
||||||
|
```bash
|
||||||
|
# Deploy already-built images (e.g., rollback to previous version)
|
||||||
|
git commit --allow-empty -m "deploy_only: Rollback to v1.2.9"
|
||||||
|
git tag deploy-v1.2.9
|
||||||
|
git push && git push --tags
|
||||||
|
|
||||||
|
# Or deploy latest images
|
||||||
|
git commit --allow-empty -m "deploy_only: Deploy latest"
|
||||||
|
git tag deploy-latest
|
||||||
|
git push && git push --tags
|
||||||
|
```
|
||||||
|
|
||||||
|
**What happens**:
|
||||||
|
- Skips building entirely
|
||||||
|
- Deploys specified tag's images (or `latest`)
|
||||||
- Duration: ~1 minute
|
- Duration: ~1 minute
|
||||||
- Example: `git commit --allow-empty -m "deploy_only: Deploy v1.2.9"`
|
|
||||||
|
## Development Workflows
|
||||||
|
|
||||||
|
### Making Changes to a Single Service
|
||||||
|
|
||||||
|
When working on a specific service (e.g., telegram-listener):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Navigate to the submodule
|
||||||
|
cd telegram-listener
|
||||||
|
|
||||||
|
# 2. Create a feature branch in the submodule
|
||||||
|
git checkout -b feature/new-feature
|
||||||
|
|
||||||
|
# 3. Make your changes to the code
|
||||||
|
# ... edit files ...
|
||||||
|
|
||||||
|
# 4. Test locally (if tests exist)
|
||||||
|
dotnet test
|
||||||
|
|
||||||
|
# 5. Commit and push in the submodule
|
||||||
|
git add .
|
||||||
|
git commit -m "Add new feature"
|
||||||
|
git push origin feature/new-feature
|
||||||
|
|
||||||
|
# 6. Return to parent repo and update submodule reference
|
||||||
|
cd ..
|
||||||
|
git add telegram-listener
|
||||||
|
git commit -m "Update telegram-listener: Add new feature"
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
### Updating Contract Packages
|
||||||
|
|
||||||
|
When you change event contracts (Async.Api.Contracts) or REST contracts (Api.Contracts):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Make changes to contracts in the submodule
|
||||||
|
cd text-matcher
|
||||||
|
# ... edit Nocr.TextMatcher.Async.Api.Contracts ...
|
||||||
|
git add . && git commit -m "Add new event contract"
|
||||||
|
git push origin main
|
||||||
|
|
||||||
|
# 2. Return to parent repo and publish contracts only
|
||||||
|
cd ..
|
||||||
|
git add text-matcher
|
||||||
|
git commit -m "contracts_only:text_matcher - Add new event contract"
|
||||||
|
git tag 0.8.6
|
||||||
|
git push && git push --tags
|
||||||
|
|
||||||
|
# 3. Other services can now reference the new contract version
|
||||||
|
# Update their .csproj or Directory.Packages.props to use version 0.8.6
|
||||||
|
```
|
||||||
|
|
||||||
|
### Working Across Multiple Services
|
||||||
|
|
||||||
|
When implementing a feature that spans multiple services:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Update each submodule in sequence
|
||||||
|
cd telegram-listener
|
||||||
|
git checkout -b feature/cross-service-feature
|
||||||
|
# ... make changes ...
|
||||||
|
git commit -m "Part 1: Update listener"
|
||||||
|
git push origin feature/cross-service-feature
|
||||||
|
|
||||||
|
cd ../text-matcher
|
||||||
|
git checkout -b feature/cross-service-feature
|
||||||
|
# ... make changes ...
|
||||||
|
git commit -m "Part 2: Update matcher"
|
||||||
|
git push origin feature/cross-service-feature
|
||||||
|
|
||||||
|
# 2. Update parent repo to reference all changes
|
||||||
|
cd ..
|
||||||
|
git add telegram-listener text-matcher
|
||||||
|
git commit -m "Implement cross-service feature"
|
||||||
|
git push origin main
|
||||||
|
|
||||||
|
# 3. Tag for full release
|
||||||
|
git tag v1.5.0
|
||||||
|
git push --tags
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common CI/CD Workflows
|
||||||
|
|
||||||
|
### Test a Feature Branch
|
||||||
|
```bash
|
||||||
|
git checkout -b feature/add-logging
|
||||||
|
# ... make changes ...
|
||||||
|
git add . && git commit -m "Add structured logging"
|
||||||
|
git push origin feature/add-logging
|
||||||
|
# ✅ Drone runs feature-validation pipeline
|
||||||
|
```
|
||||||
|
|
||||||
|
### Publish Contracts After API Changes
|
||||||
|
```bash
|
||||||
|
cd text-matcher
|
||||||
|
# Update Nocr.TextMatcher.Async.Api.Contracts
|
||||||
|
git add . && git commit -m "Add UserDeleted event"
|
||||||
|
git push
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
git add text-matcher
|
||||||
|
git commit -m "contracts_only:text_matcher - Add UserDeleted event"
|
||||||
|
git tag 0.8.5
|
||||||
|
git push && git push --tags
|
||||||
|
# ✅ Drone publishes text-matcher contracts to NuGet
|
||||||
|
```
|
||||||
|
|
||||||
|
### Full Release Workflow
|
||||||
|
```bash
|
||||||
|
# Work on main branch
|
||||||
|
git add .
|
||||||
|
git commit -m "Implement payment processing"
|
||||||
|
git push
|
||||||
|
# ✅ Drone runs main-validation
|
||||||
|
|
||||||
|
# Tag for release
|
||||||
|
git tag v2.0.0
|
||||||
|
git push --tags
|
||||||
|
# ✅ Drone runs full-release pipeline:
|
||||||
|
# 1. Publishes all contracts
|
||||||
|
# 2. Builds all Docker images
|
||||||
|
# 3. Deploys to Kubernetes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Emergency Rollback
|
||||||
|
```bash
|
||||||
|
# Rollback to last known good version
|
||||||
|
git commit --allow-empty -m "deploy_only: Emergency rollback to v1.9.5"
|
||||||
|
git tag rollback-v1.9.5
|
||||||
|
git push && git push --tags
|
||||||
|
# ✅ Drone deploys v1.9.5 images immediately (~1 minute)
|
||||||
|
```
|
||||||
|
|
||||||
### Deployment Scripts
|
### Deployment Scripts
|
||||||
|
|
||||||
@ -195,4 +473,83 @@ Located in `_deploy/scripts/`:
|
|||||||
- **Parallel execution** for independent operations
|
- **Parallel execution** for independent operations
|
||||||
- **Proper dependency order**: Contracts → Images → Deploy
|
- **Proper dependency order**: Contracts → Images → Deploy
|
||||||
- **Kaniko layer caching** for faster Docker builds
|
- **Kaniko layer caching** for faster Docker builds
|
||||||
- **Docker-in-Docker** support for Testcontainers in tests
|
- **Docker-in-Docker** support for Testcontainers in tests
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Submodule Issues
|
||||||
|
|
||||||
|
**Problem:** Submodule directories are empty after cloning
|
||||||
|
```bash
|
||||||
|
# Solution: Initialize submodules
|
||||||
|
git submodule update --init --recursive
|
||||||
|
```
|
||||||
|
|
||||||
|
**Problem:** Submodule is in detached HEAD state
|
||||||
|
```bash
|
||||||
|
# Solution: Check out the main branch in the submodule
|
||||||
|
cd <submodule-name>
|
||||||
|
git checkout main
|
||||||
|
git pull origin main
|
||||||
|
cd ..
|
||||||
|
```
|
||||||
|
|
||||||
|
**Problem:** Changes in submodule not reflected in parent repo
|
||||||
|
```bash
|
||||||
|
# Solution: Update submodule reference in parent
|
||||||
|
cd .. # Return to parent repo
|
||||||
|
git add <submodule-name>
|
||||||
|
git commit -m "Update <submodule-name> reference"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build Issues
|
||||||
|
|
||||||
|
**Problem:** NuGet package restore fails with NU1507 warning
|
||||||
|
```bash
|
||||||
|
# Solution: Copy nuget.config to submodule root
|
||||||
|
cp nuget.config telegram-listener/
|
||||||
|
cd telegram-listener && dotnet restore
|
||||||
|
```
|
||||||
|
|
||||||
|
**Problem:** Cannot find Nocr.* contract packages
|
||||||
|
```bash
|
||||||
|
# Solution: Ensure you have access to the private NuGet feed
|
||||||
|
# Check nuget.config has the correct source configuration
|
||||||
|
# Verify credentials for the "musk" package source
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Compose Issues
|
||||||
|
|
||||||
|
**Problem:** Service cannot connect to RabbitMQ
|
||||||
|
```bash
|
||||||
|
# Solution: Use the Docker network hostname, not localhost
|
||||||
|
# In docker-compose environment: nocr-rabbitmq:5672
|
||||||
|
# In local development: localhost:5672
|
||||||
|
```
|
||||||
|
|
||||||
|
**Problem:** Database connection fails
|
||||||
|
```bash
|
||||||
|
# Solution: Wait for database health checks to pass
|
||||||
|
# Check docker-compose logs for database container
|
||||||
|
docker-compose logs nocr-text-matcher-db
|
||||||
|
# Database takes 10-30 seconds to be ready on first start
|
||||||
|
```
|
||||||
|
|
||||||
|
### CI/CD Issues
|
||||||
|
|
||||||
|
**Problem:** Pipeline doesn't trigger on tag
|
||||||
|
```bash
|
||||||
|
# Solution: Ensure tag matches expected patterns
|
||||||
|
# Feature validation: feature/*, fix/*, issues/*
|
||||||
|
# Main validation: main branch
|
||||||
|
# Contracts: Tag with commit message containing "contracts_only:<service>"
|
||||||
|
# Full release: Any tag without special markers
|
||||||
|
# Deploy-only: Tag with commit message containing "deploy_only:"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Problem:** Docker image build fails in Kaniko
|
||||||
|
```bash
|
||||||
|
# Solution: Check if nuget.config is correctly copied
|
||||||
|
# Verify _deploy/deploy.sh contains nuget.config copy step
|
||||||
|
# Check Drone logs for nuget.config presence in build context
|
||||||
|
```
|
||||||
@ -110,7 +110,7 @@ git push origin v1.3.0
|
|||||||
---
|
---
|
||||||
|
|
||||||
### Пайплайн 5: **Deploy-Only (Только деплой)**
|
### Пайплайн 5: **Deploy-Only (Только деплой)**
|
||||||
**Триггер:** Тег с сообщением коммита, содержащим `deploy_only:`
|
**Триггер:** Тег с сообщением коммита, содержащим `deploy_only: <version>`
|
||||||
**Назначение:** Быстрый деплой уже собранных образов
|
**Назначение:** Быстрый деплой уже собранных образов
|
||||||
**Длительность:** ~1 минута
|
**Длительность:** ~1 минута
|
||||||
|
|
||||||
@ -119,14 +119,26 @@ git push origin v1.3.0
|
|||||||
- Деплоит указанные образы в Kubernetes
|
- Деплоит указанные образы в Kubernetes
|
||||||
- Полезно для отката или продвижения существующих образов
|
- Полезно для отката или продвижения существующих образов
|
||||||
|
|
||||||
|
**ВАЖНО:** В сообщении коммита нужно указать версию образов для деплоя:
|
||||||
|
|
||||||
**Пример рабочего процесса:**
|
**Пример рабочего процесса:**
|
||||||
```bash
|
```bash
|
||||||
# Деплой существующих образов
|
# Деплой существующих образов v1.2.9
|
||||||
git commit --allow-empty -m "deploy_only: Deploy v1.2.9"
|
git commit --allow-empty -m "deploy_only: v1.2.9"
|
||||||
git tag v1.2.9-deploy
|
git tag deploy-v1.2.9
|
||||||
git push origin v1.2.9-deploy
|
git push origin deploy-v1.2.9
|
||||||
|
|
||||||
|
# Откат на предыдущую версию v1.2.8
|
||||||
|
git commit --allow-empty -m "deploy_only: v1.2.8"
|
||||||
|
git tag rollback-v1.2.8
|
||||||
|
git push origin rollback-v1.2.8
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Формат commit message:**
|
||||||
|
- `deploy_only: v1.2.9` - деплоит образы с тегом `v1.2.9`
|
||||||
|
- Скрипт извлекает версию из сообщения и использует соответствующие образы
|
||||||
|
- Образы должны существовать в registry (собраны ранее через full-release)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🛠️ Скрипты деплоя
|
## 🛠️ Скрипты деплоя
|
||||||
@ -137,10 +149,18 @@ git push origin v1.2.9-deploy
|
|||||||
**Назначение:** Деплой сервисов в Kubernetes
|
**Назначение:** Деплой сервисов в Kubernetes
|
||||||
**Использование:**
|
**Использование:**
|
||||||
```bash
|
```bash
|
||||||
./deploy.sh <tag> <commit-sha>
|
# Full release (использует TAG для образов)
|
||||||
./deploy.sh v1.3.0 abc1234
|
./deploy.sh v1.3.0 abc1234
|
||||||
|
|
||||||
|
# Deploy only (переопределяет тег образа)
|
||||||
|
./deploy.sh deploy-v1.2.9 def5678 v1.2.9
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Параметры:**
|
||||||
|
1. `tag` - Git тег (обязательный)
|
||||||
|
2. `commit-sha` - SHA коммита (опциональный)
|
||||||
|
3. `image-tag-override` - Переопределение тега образа (опциональный, для deploy_only)
|
||||||
|
|
||||||
**Возможности:**
|
**Возможности:**
|
||||||
- Обновляет deployment-манифесты новыми тегами образов
|
- Обновляет deployment-манифесты новыми тегами образов
|
||||||
- Применяет манифесты в кластер
|
- Применяет манифесты в кластер
|
||||||
@ -256,9 +276,9 @@ Push в main → Main Validation (сборка + тесты)
|
|||||||
4. **Экстренный откат**
|
4. **Экстренный откат**
|
||||||
```bash
|
```bash
|
||||||
# Быстрый откат через deploy-only
|
# Быстрый откат через deploy-only
|
||||||
git commit --allow-empty -m "deploy_only: Rollback to v1.2.8"
|
git commit --allow-empty -m "deploy_only: v1.2.8"
|
||||||
git tag v1.2.8-rollback
|
git tag rollback-v1.2.8
|
||||||
git push origin v1.2.8-rollback
|
git push origin rollback-v1.2.8
|
||||||
|
|
||||||
# Или используйте скрипт отката напрямую в кластере
|
# Или используйте скрипт отката напрямую в кластере
|
||||||
kubectl exec -it deploy-pod -- bash
|
kubectl exec -it deploy-pod -- bash
|
||||||
|
|||||||
@ -4,20 +4,34 @@ set -e
|
|||||||
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
# 🚀 Nocr Services Deployment Script
|
# 🚀 Nocr Services Deployment Script
|
||||||
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
# Usage: ./deploy.sh <tag> <commit-sha>
|
# Usage: ./deploy.sh <tag> [commit-sha] [image-tag-override]
|
||||||
# Example: ./deploy.sh v1.2.3 abc1234
|
# Examples:
|
||||||
|
# Full release: ./deploy.sh v1.2.3 abc1234
|
||||||
|
# Deploy only: ./deploy.sh deploy-v1.2.3 def5678 v1.2.3
|
||||||
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
|
||||||
TAG=${1:-latest}
|
TAG=${1:-latest}
|
||||||
COMMIT_SHA=${2:-latest}
|
COMMIT_SHA=${2:-}
|
||||||
NAMESPACE="nocr"
|
NAMESPACE="nocr"
|
||||||
DEPLOYMENT_FILE="../k8s/deployment.yaml"
|
DEPLOYMENT_FILE="../k8s/deployment.yaml"
|
||||||
|
IMAGE_TAG_OVERRIDE=${3:-}
|
||||||
|
|
||||||
|
# Determine image tag to use
|
||||||
|
# Priority: 1) IMAGE_TAG_OVERRIDE (from command line), 2) TAG
|
||||||
|
if [ -n "$IMAGE_TAG_OVERRIDE" ]; then
|
||||||
|
IMAGE_TAG=$IMAGE_TAG_OVERRIDE
|
||||||
|
else
|
||||||
|
IMAGE_TAG=${TAG}
|
||||||
|
fi
|
||||||
|
|
||||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
echo "🚀 Starting deployment of Nocr services"
|
echo "🚀 Starting deployment of Nocr services"
|
||||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
echo "📦 Tag: $TAG"
|
echo "📦 Tag: $TAG"
|
||||||
echo "📝 Commit SHA: $COMMIT_SHA"
|
echo "🏷️ Image Tag: $IMAGE_TAG"
|
||||||
|
if [ -n "$COMMIT_SHA" ]; then
|
||||||
|
echo "📝 Commit SHA: $COMMIT_SHA"
|
||||||
|
fi
|
||||||
echo "🎯 Namespace: $NAMESPACE"
|
echo "🎯 Namespace: $NAMESPACE"
|
||||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
|
||||||
@ -42,12 +56,12 @@ cp "$DEPLOYMENT_FILE" "$TEMP_DEPLOYMENT"
|
|||||||
echo "🔧 Updating image tags in deployment manifests..."
|
echo "🔧 Updating image tags in deployment manifests..."
|
||||||
|
|
||||||
# Update image tags for all services
|
# Update image tags for all services
|
||||||
sed -i "s|hub.musk.fun/k8s/nocr/telegram_listener:.*|hub.musk.fun/k8s/nocr/telegram_listener:${COMMIT_SHA}|g" "$TEMP_DEPLOYMENT"
|
sed -i "s|hub.musk.fun/k8s/nocr/telegram_listener:.*|hub.musk.fun/k8s/nocr/telegram_listener:${IMAGE_TAG}|g" "$TEMP_DEPLOYMENT"
|
||||||
sed -i "s|hub.musk.fun/k8s/nocr/telegram_client:.*|hub.musk.fun/k8s/nocr/telegram_client:${COMMIT_SHA}|g" "$TEMP_DEPLOYMENT"
|
sed -i "s|hub.musk.fun/k8s/nocr/telegram_client:.*|hub.musk.fun/k8s/nocr/telegram_client:${IMAGE_TAG}|g" "$TEMP_DEPLOYMENT"
|
||||||
sed -i "s|hub.musk.fun/k8s/nocr/text_matcher:.*|hub.musk.fun/k8s/nocr/text_matcher:${COMMIT_SHA}|g" "$TEMP_DEPLOYMENT"
|
sed -i "s|hub.musk.fun/k8s/nocr/text_matcher:.*|hub.musk.fun/k8s/nocr/text_matcher:${IMAGE_TAG}|g" "$TEMP_DEPLOYMENT"
|
||||||
sed -i "s|hub.musk.fun/k8s/nocr/text_matcher_migrator:.*|hub.musk.fun/k8s/nocr/text_matcher_migrator:${COMMIT_SHA}|g" "$TEMP_DEPLOYMENT"
|
sed -i "s|hub.musk.fun/k8s/nocr/text_matcher_migrator:.*|hub.musk.fun/k8s/nocr/text_matcher_migrator:${IMAGE_TAG}|g" "$TEMP_DEPLOYMENT"
|
||||||
sed -i "s|hub.musk.fun/k8s/nocr/users:.*|hub.musk.fun/k8s/nocr/users:${COMMIT_SHA}|g" "$TEMP_DEPLOYMENT"
|
sed -i "s|hub.musk.fun/k8s/nocr/users:.*|hub.musk.fun/k8s/nocr/users:${IMAGE_TAG}|g" "$TEMP_DEPLOYMENT"
|
||||||
sed -i "s|hub.musk.fun/k8s/nocr/users_migrator:.*|hub.musk.fun/k8s/nocr/users_migrator:${COMMIT_SHA}|g" "$TEMP_DEPLOYMENT"
|
sed -i "s|hub.musk.fun/k8s/nocr/users_migrator:.*|hub.musk.fun/k8s/nocr/users_migrator:${IMAGE_TAG}|g" "$TEMP_DEPLOYMENT"
|
||||||
|
|
||||||
echo "✅ Image tags updated"
|
echo "✅ Image tags updated"
|
||||||
|
|
||||||
@ -60,11 +74,18 @@ rm "$TEMP_DEPLOYMENT"
|
|||||||
|
|
||||||
echo "✅ Manifests applied"
|
echo "✅ Manifests applied"
|
||||||
echo ""
|
echo ""
|
||||||
echo "⏳ Waiting for rollouts to complete..."
|
|
||||||
|
# Force restart deployments to pull latest images
|
||||||
|
echo "🔄 Restarting deployments to pull new images..."
|
||||||
|
DEPLOYMENTS=("telegram-listener" "text-matcher" "users" "telegram-client")
|
||||||
|
for deployment in "${DEPLOYMENTS[@]}"; do
|
||||||
|
kubectl rollout restart deployment/"$deployment" -n "$NAMESPACE"
|
||||||
|
echo " ↻ Restarted $deployment"
|
||||||
|
done
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Wait for each deployment to roll out
|
echo "⏳ Waiting for rollouts to complete..."
|
||||||
DEPLOYMENTS=("telegram-listener" "text-matcher" "users" "telegram-client")
|
echo ""
|
||||||
TIMEOUT="300s"
|
TIMEOUT="300s"
|
||||||
|
|
||||||
for deployment in "${DEPLOYMENTS[@]}"; do
|
for deployment in "${DEPLOYMENTS[@]}"; do
|
||||||
|
|||||||
21
nuget.config
Normal file
21
nuget.config
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<clear />
|
||||||
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||||
|
<add key="musk" value="https://gitea.musk.fun/api/packages/nocr/nuget/index.json" />
|
||||||
|
</packageSources>
|
||||||
|
|
||||||
|
<!-- Package Source Mapping for Central Package Management -->
|
||||||
|
<packageSourceMapping>
|
||||||
|
<!-- All Nocr.* packages come from the private 'musk' feed -->
|
||||||
|
<packageSource key="musk">
|
||||||
|
<package pattern="Nocr.*" />
|
||||||
|
</packageSource>
|
||||||
|
|
||||||
|
<!-- All other packages come from nuget.org -->
|
||||||
|
<packageSource key="nuget.org">
|
||||||
|
<package pattern="*" />
|
||||||
|
</packageSource>
|
||||||
|
</packageSourceMapping>
|
||||||
|
</configuration>
|
||||||
16
prepare-build.sh
Executable file
16
prepare-build.sh
Executable file
@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Prepares the build environment by copying nuget.config to all submodules
|
||||||
|
# This is required for both local docker-compose builds and CI/CD
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "📦 Copying nuget.config to all submodules..."
|
||||||
|
|
||||||
|
for submodule in telegram-client telegram-listener text-matcher users; do
|
||||||
|
if [ -d "$submodule" ]; then
|
||||||
|
cp nuget.config "$submodule/"
|
||||||
|
echo "✓ Copied to $submodule/"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "✅ Build preparation complete!"
|
||||||
@ -1 +1 @@
|
|||||||
Subproject commit a4ed855d56ce9f4241034983e0bb43cab433d70d
|
Subproject commit e8ee01cbe809867305ff02611155cddffccbb401
|
||||||
@ -1 +1 @@
|
|||||||
Subproject commit 758cb653d97bb8fce43145adc0e8075e24f82d06
|
Subproject commit 9ad504753550414edd96ef4194a3e0ee7e604e28
|
||||||
@ -1 +1 @@
|
|||||||
Subproject commit 1691de91b6991623494ab84afd29863b7cec3653
|
Subproject commit 1a55061e4b1b125d1b911f479fc830fb94cd93cc
|
||||||
2
users
2
users
@ -1 +1 @@
|
|||||||
Subproject commit fa136fc7a4efdbad3cf700f8e4ef2957929e022b
|
Subproject commit 30ae0c043ca2f8958223d6fb343b8b3e3561d727
|
||||||
Loading…
Reference in New Issue
Block a user