diff --git a/.woodpecker.yml b/.woodpecker.yml index 590e41a..5de0428 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -1,28 +1,66 @@ steps: - - name: ci + - name: lint + image: golangci/golangci-lint:latest + commands: + - golangci-lint run ./... + + - name: test image: golang:1.22-alpine commands: - - go vet ./... - go test ./... - - go build ./cmd/server/ - - name: docker-build - image: plugins/docker + - name: semgrep + image: semgrep/semgrep:latest + commands: + - > + semgrep scan --config auto --error + --exclude-rule go.lang.security.audit.net.cookie-missing-secure.cookie-missing-secure + --exclude-rule go.lang.security.audit.net.unescaped-data-in-url.unescaped-data-in-url + --exclude-rule go.lang.security.audit.xss.template-html-does-not-escape.unsafe-template-type + --exclude-rule html.security.audit.missing-integrity.missing-integrity + . + when: + - event: [push, pull_request] + + - name: gosec + image: golang:1.22-bookworm + commands: + - go install github.com/securego/gosec/v2/cmd/gosec@latest + - gosec -exclude=G120,G706,G101,G115,G203,G124 ./... + when: + - event: [push, pull_request] + + - name: trivy-fs + image: aquasec/trivy:latest + commands: + - trivy fs --severity HIGH,CRITICAL --exit-code 1 . + when: + - event: [push, pull_request] + + - name: trivy-secrets + image: aquasec/trivy:latest + commands: + - trivy fs --scanners secret --exit-code 1 . + when: + - event: [push, pull_request] + + - name: build-and-push + image: woodpeckerci/plugin-docker-buildx settings: - repo: registry.sds.dev/cast/cast-ghl-provider - registry: registry.sds.dev - tags: + repo: git.sds.dev/cast/cast-ghl-provider + registry: git.sds.dev + tag: + - ${CI_COMMIT_SHA:0:8} - latest - - "${CI_COMMIT_TAG}" username: - from_secret: docker_username + from_secret: registry_user password: - from_secret: docker_password + from_secret: registry_password when: - event: tag - ref: refs/tags/v* + - branch: main + event: push - - name: deploy-tag + - name: deploy image: appleboy/drone-ssh settings: host: @@ -30,33 +68,29 @@ steps: username: from_secret: deploy_user key: - from_secret: deploy_key + from_secret: deploy_ssh_key script: - - cd /opt/cast-ghl-provider - - docker compose pull bridge - - docker compose up -d --remove-orphans - - sleep 5 - - docker compose ps bridge + - bash /opt/cast-ghl-provider/deploy/deploy.sh when: - event: tag - ref: refs/tags/v* + - branch: main + event: push - - name: deploy-main - image: appleboy/drone-ssh + - name: notify-telegram + image: appleboy/drone-telegram settings: - host: - from_secret: deploy_host - username: - from_secret: deploy_user - key: - from_secret: deploy_key - script: - - cd /opt/cast-ghl-provider - - git pull --ff-only - - docker compose build --no-cache bridge - - docker compose up -d --remove-orphans - - sleep 5 - - docker compose ps bridge + token: + from_secret: telegram_bot_token + to: + from_secret: telegram_chat_id + message: > + {{#success build.status}}✅{{else}}❌{{/success}} **{{repo.name}}** + + Branch: `{{commit.branch}}` + + Status: **{{build.status}}** + + Commit: `{{commit.message}}` + + {{build.link}} when: - branch: main - event: push + - status: [success, failure] diff --git a/deploy/deploy.sh b/deploy/deploy.sh index f687289..83ac944 100644 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -1,37 +1,22 @@ #!/usr/bin/env bash -# deploy.sh — Manual redeploy on an existing Docker server. -# Normally Woodpecker CI handles deploys automatically on push to main or tag. -# Use this script only for manual/emergency redeploys. -# Usage: bash deploy/deploy.sh [--from-registry] -# --from-registry Pull the pre-built image from registry instead of building locally +# deploy.sh — Called by Woodpecker CI on every push to main. +# Can also be run manually for emergency redeployments. +# Pulls the latest image from the registry and restarts the stack. set -euo pipefail APP_DIR="$(cd "$(dirname "$0")/.." && pwd)" cd "$APP_DIR" -FROM_REGISTRY=false -[[ "${1:-}" == "--from-registry" ]] && FROM_REGISTRY=true - -echo "==> Pulling latest code" -git pull --ff-only - -if $FROM_REGISTRY; then - echo "==> Pulling pre-built image from registry" - docker compose pull bridge -else - echo "==> Building image locally" - docker compose build --no-cache bridge -fi +echo "==> Pulling latest image from registry" +docker compose pull bridge echo "==> Restarting services" docker compose up -d --remove-orphans -echo "==> Waiting for health check" -sleep 5 +echo "==> Status" +sleep 3 docker compose ps bridge -docker compose logs --tail=20 bridge echo "" -echo "=== Deploy complete ===" -echo "Health endpoint: https://hl.cast.ph/health" +echo "=== Deploy complete — https://hl.cast.ph/health ===" diff --git a/docker-compose.yaml b/docker-compose.yaml index 6c747a4..58c3dc2 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,6 +1,7 @@ services: bridge: - build: . + image: git.sds.dev/cast/cast-ghl-provider:latest + build: . # used only for local dev (docker compose up --build); production uses the registry image # No port binding — nginx-proxy routes traffic via the shared proxy network env_file: .env environment: