name: CI and deploy on: pull_request: push: branches: - main workflow_dispatch: permissions: contents: read concurrency: group: tarakan-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: false jobs: test: name: Test runs-on: ubuntu-24.04 services: postgres: image: postgres:16 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres ports: - 5432:5432 options: >- --health-cmd "pg_isready -U postgres" --health-interval 5s --health-timeout 5s --health-retries 10 env: MIX_ENV: test steps: - name: Check out source uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Run pre-commit checks run: | docker run --rm --network host \ --volume "$GITHUB_WORKSPACE:/app" \ --workdir /app \ --env MIX_ENV=test \ docker.io/hexpm/elixir:1.20.1-erlang-29.0.2-debian-trixie-20260610-slim \ bash -lc ' apt-get update apt-get install -y --no-install-recommends build-essential git openssh-client mix local.hex --force mix local.rebar --force mix deps.get mix precommit ' deploy: name: Deploy production needs: test if: >- github.ref == 'refs/heads/main' && github.event_name != 'pull_request' runs-on: ubuntu-24.04 env: DEPLOY_HOST: 66.42.113.222 DEPLOY_USER: tarakan-deploy IMAGE: tarakan-app:${{ github.sha }} steps: - name: Check out source uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Build production image run: docker build --pull -f deploy/docker/Dockerfile --tag "$IMAGE" . - name: Package production image run: docker save "$IMAGE" | gzip -1 > /tmp/tarakan-image.tar.gz - name: Configure deployment SSH env: DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }} # Prefer secret/var; fall back to the production host key pin. DEPLOY_SSH_HOST_KEY: ${{ secrets.DEPLOY_SSH_HOST_KEY || vars.DEPLOY_SSH_HOST_KEY || '66.42.113.222 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINdLaUbq4l8akmbiTurBX3F1nTw8AxJZ1efIN3t2ptGq' }} run: | install -d -m 0700 ~/.ssh printf '%s\n' "$DEPLOY_SSH_KEY" > ~/.ssh/id_ed25519 chmod 0600 ~/.ssh/id_ed25519 { printf '%s\n' "$DEPLOY_SSH_HOST_KEY" while IFS= read -r line; do case "$line" in ''|'#'*) continue ;; esac host_field="${line%% *}" rest="${line#* }" if [[ "$host_field" == *@* ]]; then printf '%s %s\n' "${host_field##*@}" "$rest" fi done <<< "$DEPLOY_SSH_HOST_KEY" } > ~/.ssh/known_hosts chmod 0600 ~/.ssh/known_hosts - name: Upload release run: | rsync -az --delete-delay \ --chown="$DEPLOY_USER:linuxuser" \ --chmod=D755,F644 \ --exclude='.git/' \ --exclude='.env' \ --exclude='.deploy/' \ --exclude='.secrets/' \ --exclude='backups/' \ --exclude='_build/' \ --exclude='deps/' \ --exclude='tmp/' \ --exclude='erl_crash.dump' \ --exclude='assets/node_modules/' \ --exclude='priv/hosted/' \ --exclude='priv/mirrors/' \ --exclude='priv/ssh/' \ --exclude='priv/static/assets/' \ --exclude='priv/static/cache_manifest.json' \ ./ "$DEPLOY_USER@$DEPLOY_HOST:/opt/tarakan/" # Executable deploy scripts (rsync F644 would strip +x). ssh "$DEPLOY_USER@$DEPLOY_HOST" \ "chmod 755 /opt/tarakan/scripts/deploy/*.sh /opt/tarakan/ops/*.sh 2>/dev/null || true" rsync -az /tmp/tarakan-image.tar.gz \ "$DEPLOY_USER@$DEPLOY_HOST:/opt/tarakan/.deploy/tarakan-image.tar.gz" - name: Activate release run: ssh "$DEPLOY_USER@$DEPLOY_HOST" "cd /opt/tarakan && ./scripts/deploy/deploy.sh '$IMAGE'"