diff --git a/.drone.yml b/.drone.yml index d0b71d4..3d74ead 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,3 +1,100 @@ +--- +# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +# 🧪 Pipeline 1: Feature Branch Validation +# Trigger: Push to feature/* or fix/* branches +# Purpose: Fast feedback for developers - build and test only +# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +kind: pipeline +type: kubernetes +name: feature-validation + +metadata: + namespace: musk-drone + +trigger: + ref: + - refs/heads/feature/* + - refs/heads/issues/* + - refs/heads/fix/* + event: + - push + +clone: + disable: true + +# Service container for Testcontainers +services: + - name: docker + image: docker:27-dind + privileged: true + volumes: + - name: dockersock + path: /var/run + +volumes: + - name: dockersock + temp: {} + - name: nuget-cache + temp: {} + +steps: + - name: clone + image: alpine/git + commands: + - git clone https://gitea.musk.fun/nocr/flea + - cd flea + - git checkout $DRONE_COMMIT + - git submodule update --init --recursive + + - name: dotnet-restore + image: mcr.microsoft.com/dotnet/sdk:8.0 + volumes: + - name: nuget-cache + path: /root/.nuget/packages + commands: + - cd flea + - dotnet nuget add source --name musk https://gitea.musk.fun/api/packages/nocr/nuget/index.json + - echo "🔄 Restoring all projects..." + - dotnet restore telegram-listener/Nocr.TelegramListener.sln + - dotnet restore telegram-client/Nocr.TelegramClient.sln + - dotnet restore text-matcher/Nocr.TextMatcher.sln + - dotnet restore users/Nocr.Users.sln + depends_on: + - clone + + - name: dotnet-build + image: mcr.microsoft.com/dotnet/sdk:8.0 + volumes: + - name: nuget-cache + path: /root/.nuget/packages + commands: + - cd flea + - echo "🔨 Building all projects..." + - dotnet build telegram-listener/Nocr.TelegramListener.sln --no-restore -c Debug + - dotnet build telegram-client/Nocr.TelegramClient.sln --no-restore -c Debug + - dotnet build text-matcher/Nocr.TextMatcher.sln --no-restore -c Debug + - dotnet build users/Nocr.Users.sln --no-restore -c Debug + depends_on: + - dotnet-restore + + - name: dotnet-test + image: mcr.microsoft.com/dotnet/sdk:8.0 + volumes: + - name: nuget-cache + path: /root/.nuget/packages + - name: dockersock + path: /var/run + environment: + DOCKER_HOST: unix:///var/run/docker.sock + commands: + - cd flea + - echo "🧪 Running tests..." + - dotnet test text-matcher/Nocr.TextMatcher.sln --no-build -c Debug --logger trx --results-directory ./test-results + - echo "✅ Tests completed" + depends_on: + - dotnet-build + - docker + --- # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # 📝 Pipeline 2: Main Branch Validation @@ -87,3 +184,455 @@ steps: depends_on: - dotnet-build - docker + +--- +# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +# 📦 Pipeline 3: Contracts-Only Publish +# Trigger: Tag with commit message containing "contracts_only:" +# Purpose: Fast publish of contract packages without building images +# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +kind: pipeline +type: kubernetes +name: contracts-publish + +metadata: + namespace: musk-drone + +trigger: + ref: + - refs/tags/* + event: + - tag + +clone: + disable: true + +volumes: + - name: nuget-cache + temp: {} + +steps: + - name: clone + image: alpine/git + commands: + - git clone https://gitea.musk.fun/nocr/flea + - cd flea + - git checkout $DRONE_TAG + - git submodule update --init --recursive + + - name: check-trigger + image: alpine/git + commands: + - cd flea + - COMMIT_MSG=$(git log -1 --pretty=%B) + - echo "Commit message - $COMMIT_MSG" + - | + if echo "$COMMIT_MSG" | grep -q "contracts_only:"; then + echo "✅ contracts_only detected, proceeding..." + exit 0 + else + echo "⏭️ No contracts_only marker, skipping..." + exit 78 + fi + depends_on: + - clone + + - name: telegram-listener-contracts + image: mcr.microsoft.com/dotnet/sdk:8.0 + volumes: + - name: nuget-cache + path: /root/.nuget/packages + environment: + NUGETAPIKEY: + from_secret: nuget_musk_api_key + commands: + - cd flea + - COMMIT_MSG=$(git log -1 --pretty=%B) + - | + if echo "$COMMIT_MSG" | grep -q "contracts_only:telegram_listener"; then + echo "📦 Publishing telegram-listener contracts..." + dotnet nuget add source --name musk https://gitea.musk.fun/api/packages/nocr/nuget/index.json + 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 + else + echo "⏭️ Skipping telegram-listener contracts" + fi + depends_on: + - check-trigger + + - name: text-matcher-contracts + image: mcr.microsoft.com/dotnet/sdk:8.0 + volumes: + - name: nuget-cache + path: /root/.nuget/packages + environment: + NUGETAPIKEY: + from_secret: nuget_musk_api_key + commands: + - cd flea + - COMMIT_MSG=$(git log -1 --pretty=%B) + - | + if echo "$COMMIT_MSG" | grep -q "contracts_only:text_matcher"; then + echo "📦 Publishing text-matcher contracts..." + dotnet nuget add source --name musk https://gitea.musk.fun/api/packages/nocr/nuget/index.json + 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 + else + echo "⏭️ Skipping text-matcher contracts" + fi + depends_on: + - check-trigger + + - name: users-contracts + image: mcr.microsoft.com/dotnet/sdk:8.0 + volumes: + - name: nuget-cache + path: /root/.nuget/packages + environment: + NUGETAPIKEY: + from_secret: nuget_musk_api_key + commands: + - cd flea + - COMMIT_MSG=$(git log -1 --pretty=%B) + - | + if echo "$COMMIT_MSG" | grep -q "contracts_only:users"; then + echo "📦 Publishing users contracts..." + dotnet nuget add source --name musk https://gitea.musk.fun/api/packages/nocr/nuget/index.json + 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 + else + echo "⏭️ Skipping users contracts" + fi + depends_on: + - check-trigger + +--- +# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +# 🚀 Pipeline 4: Full Release +# Trigger: Tag on main branch WITHOUT "contracts_only" or "deploy_only" +# Purpose: Full release cycle - contracts → images → optional deploy +# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +kind: pipeline +type: kubernetes +name: full-release + +metadata: + namespace: musk-drone + +trigger: + ref: + - refs/tags/* + event: + - tag + branch: + - main + +clone: + disable: true + +volumes: + - name: nuget-cache + temp: {} + +steps: + - name: clone + image: alpine/git + commands: + - git clone https://gitea.musk.fun/nocr/flea + - cd flea + - git checkout $DRONE_TAG + - git submodule update --init --recursive + + - name: check-trigger + image: alpine/git + commands: + - cd flea + - COMMIT_MSG=$(git log -1 --pretty=%B) + - echo "Commit message - $COMMIT_MSG" + - | + if echo "$COMMIT_MSG" | grep -qE "contracts_only:|deploy_only:"; then + echo "⏭️ contracts_only or deploy_only detected, skipping full release..." + exit 78 + else + echo "✅ Full release triggered" + exit 0 + fi + depends_on: + - clone + + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + # STAGE 1: Publish NuGet Contracts (sequental) + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + - name: telegram-listener-nuget + image: mcr.microsoft.com/dotnet/sdk:8.0 + volumes: + - name: nuget-cache + path: /root/.nuget/packages + environment: + NUGETAPIKEY: + from_secret: nuget_musk_api_key + commands: + - cd flea + - dotnet nuget add source --name musk https://gitea.musk.fun/api/packages/nocr/nuget/index.json + - 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 + depends_on: + - check-trigger + + - name: text-matcher-nuget + image: mcr.microsoft.com/dotnet/sdk:8.0 + volumes: + - name: nuget-cache + path: /root/.nuget/packages + environment: + NUGETAPIKEY: + from_secret: nuget_musk_api_key + commands: + - cd flea + - dotnet nuget add source --name musk https://gitea.musk.fun/api/packages/nocr/nuget/index.json + - 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 + depends_on: + - check-trigger + - telegram-listener-nuget + + - name: users-nuget + image: mcr.microsoft.com/dotnet/sdk:8.0 + volumes: + - name: nuget-cache + path: /root/.nuget/packages + environment: + NUGETAPIKEY: + from_secret: nuget_musk_api_key + commands: + - cd flea + - dotnet nuget add source --name musk https://gitea.musk.fun/api/packages/nocr/nuget/index.json + - 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 + depends_on: + - check-trigger + - text-matcher-nuget + + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + # STAGE 2: Build Docker Images with Kaniko (3 parallel streams) + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + - name: telegram-listener-build-push + image: gcr.io/kaniko-project/executor:debug + environment: + HUB_USERNAME: + from_secret: hub_username + HUB_PASSWORD: + from_secret: hub_password + commands: + - mkdir -p /kaniko/.docker + - echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json + - cd flea/telegram-listener + - /kaniko/executor + --context=. + --dockerfile=src/Nocr.TelegramListener.Host/Dockerfile + --destination=hub.musk.fun/k8s/nocr/telegram_listener:${DRONE_COMMIT_SHA:0:7} + --destination=hub.musk.fun/k8s/nocr/telegram_listener:${DRONE_TAG} + --destination=hub.musk.fun/k8s/nocr/telegram_listener:latest + --cache=true + --cache-repo=hub.musk.fun/k8s/cache/nocr-telegram-listener + --compressed-caching=true + depends_on: + - telegram-listener-nuget + - text-matcher-nuget + - users-nuget + + - name: telegram-client-build-push + image: gcr.io/kaniko-project/executor:debug + environment: + HUB_USERNAME: + from_secret: hub_username + HUB_PASSWORD: + from_secret: hub_password + commands: + - mkdir -p /kaniko/.docker + - echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json + - cd flea/telegram-client + - /kaniko/executor + --context=. + --dockerfile=src/Nocr.TelegramClient.Host/Dockerfile + --destination=hub.musk.fun/k8s/nocr/telegram_client:${DRONE_COMMIT_SHA:0:7} + --destination=hub.musk.fun/k8s/nocr/telegram_client:${DRONE_TAG} + --destination=hub.musk.fun/k8s/nocr/telegram_client:latest + --cache=true + --cache-repo=hub.musk.fun/k8s/cache/nocr-telegram-client + --compressed-caching=true + depends_on: + - telegram-listener-build-push + + - name: text-matcher-build-push + image: gcr.io/kaniko-project/executor:debug + environment: + HUB_USERNAME: + from_secret: hub_username + HUB_PASSWORD: + from_secret: hub_password + commands: + - mkdir -p /kaniko/.docker + - echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json + - cd flea/text-matcher + - /kaniko/executor + --context=. + --dockerfile=src/Nocr.TextMatcher.Host/Dockerfile + --destination=hub.musk.fun/k8s/nocr/text_matcher:${DRONE_COMMIT_SHA:0:7} + --destination=hub.musk.fun/k8s/nocr/text_matcher:${DRONE_TAG} + --destination=hub.musk.fun/k8s/nocr/text_matcher:latest + --cache=true + --cache-repo=hub.musk.fun/k8s/cache/nocr-text-matcher + --compressed-caching=true + depends_on: + - telegram-listener-nuget + - text-matcher-nuget + - users-nuget + + - name: text-matcher-migrator-build-push + image: gcr.io/kaniko-project/executor:debug + environment: + HUB_USERNAME: + from_secret: hub_username + HUB_PASSWORD: + from_secret: hub_password + commands: + - mkdir -p /kaniko/.docker + - echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json + - cd flea/text-matcher + - /kaniko/executor + --context=. + --dockerfile=src/Nocr.TextMatcher.Migrator/Dockerfile + --destination=hub.musk.fun/k8s/nocr/text_matcher_migrator:${DRONE_COMMIT_SHA:0:7} + --destination=hub.musk.fun/k8s/nocr/text_matcher_migrator:${DRONE_TAG} + --destination=hub.musk.fun/k8s/nocr/text_matcher_migrator:latest + --cache=true + --cache-repo=hub.musk.fun/k8s/cache/nocr-text-matcher-migrator + --compressed-caching=true + depends_on: + - text-matcher-build-push + + - name: users-build-push + image: gcr.io/kaniko-project/executor:debug + environment: + HUB_USERNAME: + from_secret: hub_username + HUB_PASSWORD: + from_secret: hub_password + commands: + - mkdir -p /kaniko/.docker + - echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json + - cd flea/users + - /kaniko/executor + --context=. + --dockerfile=src/Nocr.Users.Host/Dockerfile + --destination=hub.musk.fun/k8s/nocr/users:${DRONE_COMMIT_SHA:0:7} + --destination=hub.musk.fun/k8s/nocr/users:${DRONE_TAG} + --destination=hub.musk.fun/k8s/nocr/users:latest + --cache=true + --cache-repo=hub.musk.fun/k8s/cache/nocr-users + --compressed-caching=true + depends_on: + - telegram-listener-nuget + - text-matcher-nuget + - users-nuget + + - name: users-migrator-build-push + image: gcr.io/kaniko-project/executor:debug + environment: + HUB_USERNAME: + from_secret: hub_username + HUB_PASSWORD: + from_secret: hub_password + commands: + - mkdir -p /kaniko/.docker + - echo "{\"auths\":{\"hub.musk.fun\":{\"username\":\"$HUB_USERNAME\",\"password\":\"$HUB_PASSWORD\"}}}" > /kaniko/.docker/config.json + - cd flea/users + - /kaniko/executor + --context=. + --dockerfile=src/Nocr.Users.Migrator/Dockerfile + --destination=hub.musk.fun/k8s/nocr/users_migrator:${DRONE_COMMIT_SHA:0:7} + --destination=hub.musk.fun/k8s/nocr/users_migrator:${DRONE_TAG} + --destination=hub.musk.fun/k8s/nocr/users_migrator:latest + --cache=true + --cache-repo=hub.musk.fun/k8s/cache/nocr-users-migrator + --compressed-caching=true + depends_on: + - users-build-push + + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + # STAGE 3: Deploy to Kubernetes (optional, based on tag pattern) + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + - name: deploy-to-k8s + image: bitnami/kubectl:latest + commands: + - cd flea/_deploy/scripts + - chmod +x deploy.sh + - ./deploy.sh ${DRONE_TAG} ${DRONE_COMMIT_SHA:0:7} + depends_on: + - telegram-client-build-push + - text-matcher-migrator-build-push + - users-migrator-build-push + when: + ref: + - refs/tags/* + +--- +# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +# 🚀 Pipeline 5: Deploy-Only +# Trigger: Tag with commit message containing "deploy_only:" +# Purpose: Fast deploy of already-built images +# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +kind: pipeline +type: kubernetes +name: deploy-only + +metadata: + namespace: musk-drone + +trigger: + ref: + - refs/tags/* + event: + - tag + +clone: + disable: true + +steps: + - name: clone + image: alpine/git + commands: + - git clone https://gitea.musk.fun/nocr/flea + - cd flea + - git checkout $DRONE_TAG + - git submodule update --init --recursive + + - name: check-trigger + image: alpine/git + commands: + - cd flea + - COMMIT_MSG=$(git log -1 --pretty=%B) + - echo "Commit message - $COMMIT_MSG" + - | + if echo "$COMMIT_MSG" | grep -q "deploy_only:"; then + echo "✅ deploy_only detected, proceeding..." + exit 0 + else + echo "⏭️ No deploy_only marker, skipping..." + exit 78 + fi + depends_on: + - clone + + - name: deploy + image: bitnami/kubectl:latest + commands: + - cd flea/_deploy/scripts + - chmod +x deploy.sh + - ./deploy.sh ${DRONE_TAG} ${DRONE_COMMIT_SHA:0:7} + depends_on: + - check-trigger