Campaigns from the API fall back to the page's own copy when no model… #153
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: deploy-prober | |
| # Deploys the port-drift prober (docs/uptime-monitoring-prd.md §12) to the | |
| # DigitalOcean droplet ubuntu@scan.crawlproof.com on merges to master. | |
| # | |
| # FULLY SELF-BOOTSTRAPPING + IDEMPOTENT: the workflow installs every system | |
| # dependency (nmap, Node 20, build tools), writes the Redis env file, installs | |
| # the systemd unit, builds, and (re)starts the service on EVERY run. First run | |
| # provisions a bare droplet; later runs just update. You never SSH in to set up. | |
| # | |
| # The prober connects OUTBOUND to Redis — nothing here opens an inbound port on | |
| # the droplet (only sshd, which already exists). | |
| # | |
| # Required repo secrets: | |
| # DROPLET_SSH_KEY - private SSH key for ubuntu@scan.crawlproof.com | |
| # PROBER_REDIS_URL - rediss://... broker URL (scoped to the "prober" queue) | |
| on: | |
| push: | |
| branches: [master] | |
| paths: | |
| - "prober/**" | |
| - "lib/**" # prober shares job-payload types from lib/ | |
| - ".github/workflows/deploy-prober.yml" | |
| workflow_dispatch: # allow manual redeploys | |
| # Never let two deploys race on the droplet. | |
| concurrency: | |
| group: deploy-prober | |
| cancel-in-progress: false | |
| env: | |
| DEPLOY_HOST: scan.crawlproof.com | |
| DEPLOY_USER: ubuntu | |
| DEPLOY_PATH: /home/ubuntu/crawlproof.com | |
| jobs: | |
| deploy: | |
| name: provision + deploy prober | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Configure SSH | |
| env: | |
| DROPLET_SSH_KEY: ${{ secrets.DROPLET_SSH_KEY }} | |
| run: | | |
| install -m 700 -d ~/.ssh | |
| # Write the deploy key robustly: tolerate CRLF (a common cause of | |
| # "error in libcrypto"), and accept either a raw OpenSSH/PEM key or a | |
| # base64-encoded one. | |
| if printf '%s' "$DROPLET_SSH_KEY" | grep -q 'BEGIN'; then | |
| printf '%s\n' "$DROPLET_SSH_KEY" | tr -d '\r' > ~/.ssh/id_deploy | |
| else | |
| printf '%s' "$DROPLET_SSH_KEY" | tr -d '\r' | base64 -d > ~/.ssh/id_deploy | |
| fi | |
| chmod 600 ~/.ssh/id_deploy | |
| # Fail fast with a clear message if the key is malformed, instead of a | |
| # confusing "Permission denied (publickey)" later. | |
| if ! ssh-keygen -y -f ~/.ssh/id_deploy >/dev/null 2>&1; then | |
| echo "::error::DROPLET_SSH_KEY is not a valid private key. Re-add it preserving newlines, e.g. 'gh secret set DROPLET_SSH_KEY --repo profullstack/crawlproof.com < id_deploy' (or store it base64-encoded)." | |
| exit 1 | |
| fi | |
| ssh-keyscan -H "$DEPLOY_HOST" >> ~/.ssh/known_hosts 2>/dev/null | |
| - name: Ship prober + lib to droplet | |
| run: | | |
| ssh -i ~/.ssh/id_deploy "$DEPLOY_USER@$DEPLOY_HOST" "mkdir -p '$DEPLOY_PATH'" | |
| # --delete keeps the droplet in sync; node_modules/dist are excluded so | |
| # they are neither shipped nor deleted (rebuilt on the box). | |
| rsync -az --delete \ | |
| -e "ssh -i ~/.ssh/id_deploy" \ | |
| --exclude node_modules --exclude dist \ | |
| prober lib \ | |
| "$DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH/" | |
| - name: Provision + restart (idempotent) | |
| run: | | |
| ssh -i ~/.ssh/id_deploy "$DEPLOY_USER@$DEPLOY_HOST" \ | |
| "REDIS_URL='${{ secrets.PROBER_REDIS_URL }}' DEPLOY_PATH='$DEPLOY_PATH' bash '$DEPLOY_PATH/prober/deploy/provision.sh'" |