# Forgejo Actions: test, build/push image, deploy to production (same host as Elektrine). # Secrets: DEPLOY_SSH_KEY, DEPLOY_SSH_HOST_KEY, REGISTRY_USER, REGISTRY_TOKEN name: CI and deploy on: push: branches: [main] pull_request: workflow_dispatch: concurrency: group: haraka-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: false env: REGISTRY: git.elektrine.com IMAGE_NAME: elektrine/elektrine-haraka jobs: test: name: Test runs-on: ubuntu-latest steps: - uses: https://data.forgejo.org/actions/checkout@v4 - name: Run unit tests run: | set -euo pipefail case "$GITHUB_WORKSPACE" in /data/*) HOST_WORKSPACE="/opt/forgejo-runner/data${GITHUB_WORKSPACE#/data}" ;; *) HOST_WORKSPACE="$GITHUB_WORKSPACE" ;; esac test -f "$GITHUB_WORKSPACE/package.json" docker run --rm --network host \ --volume "$HOST_WORKSPACE:/app" \ --workdir /app \ node:20-bookworm \ bash -lc 'npm ci && npm test' build_and_deploy: name: Build, push, and deploy needs: test if: >- github.ref == 'refs/heads/main' && github.event_name != 'pull_request' runs-on: ubuntu-latest env: DEPLOY_HOST: ${{ vars.DEPLOY_HOST || 'elektrine.com' }} DEPLOY_USER: ${{ vars.DEPLOY_USER || 'elektrine-deploy' }} DEPLOY_PORT: ${{ vars.DEPLOY_PORT || '22' }} DEPLOY_PATH: ${{ vars.DEPLOY_PATH || '/opt/elektrine-haraka' }} IMAGE: git.elektrine.com/elektrine/elektrine-haraka:${{ github.sha }} IMAGE_LATEST: git.elektrine.com/elektrine/elektrine-haraka:latest steps: - uses: https://data.forgejo.org/actions/checkout@v4 - name: Log in to Forgejo registry env: REG_USER: ${{ secrets.REGISTRY_USER }} REG_PASS: ${{ secrets.REGISTRY_TOKEN }} run: | set -euo pipefail echo "$REG_PASS" | docker login "$REGISTRY" -u "$REG_USER" --password-stdin - name: Build and push image run: | set -euo pipefail docker build -t "$IMAGE" -t "$IMAGE_LATEST" . docker push "$IMAGE" docker push "$IMAGE_LATEST" echo "Pushed $IMAGE" - name: Configure SSH env: DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }} DEPLOY_SSH_HOST_KEY: ${{ secrets.DEPLOY_SSH_HOST_KEY || '66.42.127.87 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM5Vx8UDcqvgmBwDs5SlCHd8/oGDoQytGHhbbp4LNK4o' }} run: | set -euo pipefail install -d -m 0700 ~/.ssh printf '%s\n' "$DEPLOY_SSH_KEY" | sed 's/\r$//' | sed 's/\\n/\n/g' > ~/.ssh/id_ed25519 chmod 0600 ~/.ssh/id_ed25519 : > ~/.ssh/known_hosts printf '%s\n' "$DEPLOY_SSH_HOST_KEY" | sed 's/\r$//' | sed 's/\\n/\n/g' >> ~/.ssh/known_hosts ssh-keyscan -p "$DEPLOY_PORT" -T 5 -t ed25519,rsa "$DEPLOY_HOST" 2>/dev/null >> ~/.ssh/known_hosts || true ip=$(getent ahostsv4 "$DEPLOY_HOST" 2>/dev/null | awk '{print $1; exit}' || true) if [ -n "${ip:-}" ]; then ssh-keyscan -p "$DEPLOY_PORT" -T 5 -t ed25519,rsa "$ip" 2>/dev/null >> ~/.ssh/known_hosts || true fi chmod 0600 ~/.ssh/known_hosts ssh -p "$DEPLOY_PORT" \ -i "$HOME/.ssh/id_ed25519" \ -o BatchMode=yes -o IdentitiesOnly=yes \ -o StrictHostKeyChecking=yes \ -o UserKnownHostsFile="$HOME/.ssh/known_hosts" \ "$DEPLOY_USER@$DEPLOY_HOST" 'echo ssh_ok; hostname' - name: Deploy over SSH env: REG_USER: ${{ secrets.REGISTRY_USER }} REG_PASS: ${{ secrets.REGISTRY_TOKEN }} GITHUB_SHA: ${{ github.sha }} run: | set -euo pipefail ssh -p "$DEPLOY_PORT" \ -i "$HOME/.ssh/id_ed25519" \ -o BatchMode=yes -o IdentitiesOnly=yes \ -o StrictHostKeyChecking=yes \ -o UserKnownHostsFile="$HOME/.ssh/known_hosts" \ "$DEPLOY_USER@$DEPLOY_HOST" bash -s <> "\$ENV_FILE" fi if grep -q '^HARAKA_IMAGE_TAG=' "\$ENV_FILE"; then sed -i "s|^HARAKA_IMAGE_TAG=.*|HARAKA_IMAGE_TAG=\$SHA|" "\$ENV_FILE" else echo "HARAKA_IMAGE_TAG=\$SHA" >> "\$ENV_FILE" fi else echo "Warn: \$ENV_FILE not writable; using env overrides for this deploy" fi cd "\$DEPLOY_PATH/deployment" export HARAKA_IMAGE=git.elektrine.com/elektrine/elektrine-haraka export HARAKA_IMAGE_TAG="\$SHA" COMPOSE="docker compose --env-file .env -f docker-compose.same-server.yml" \$COMPOSE pull haraka-inbound haraka-submission haraka-outbound haraka-worker || true \$COMPOSE up -d haraka-inbound haraka-submission haraka-outbound haraka-worker \$COMPOSE ps docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Image}}' | grep -i haraka || true echo DEPLOY_OK EOF