2026-06-08

Pre-Launch Test Automation Guide for Web Agencies

pre-launch checklist test automation web agency CI/CD

Still Running Manual Checks Before Every Launch?

Before a client site goes live, your team opens a browser to check HTTPS, verifies the SSL certificate, tests the contact form — every time, by hand. That process works fine for two or three sites a year. Scale it to ten or twenty launches, and the risk of something slipping through multiplies with every new project.

Automating pre-launch tests solves this problem at the root. With Miterl's API and a few shell scripts, every critical check runs automatically on every launch — consistently, and with a log your team can reference or share with clients.

Why Automate Pre-Launch Testing?

The limits of manual verification

Issue Manual Automated
Missed checks Depends on individual Script runs every item without fail
Time per site 20–40 minutes 3–5 minutes
Simultaneous launches Easily overwhelmed Runs in parallel
Results are recorded Only in memory Written to a log

The cost of catching problems after a client's site goes live is detailed in "The Real Cost of Website Downtime." Pre-launch automation is the last line of defense against those costs.

What automation gives you

  • Reproducibility: New team members follow the same checklist as veterans, automatically
  • Accountability: Results are logged and can be presented to clients
  • Speed: No more waiting on manual verification before flipping the switch

Step 1: Create Monitoring Watches Before Launch

The foundation of pre-launch automation is creating Miterl monitors before the site goes live so monitoring begins the instant the domain resolves. Start by retrieving your alert contact IDs with GET /api/v1/alert-contacts.

#!/bin/bash
# pre_launch_setup.sh
# Usage: CLIENT_DOMAIN=example.com ./pre_launch_setup.sh

API_KEY="YOUR_API_KEY"
BASE_URL="https://miterl.com/api/v1"
DOMAIN="${CLIENT_DOMAIN}"
ALERT_CONTACT_IDS="[1, 2]"

# 1. HTTP uptime monitor
curl -s -X POST "${BASE_URL}/monitors" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d "{
    \"name\": \"[${DOMAIN}] HTTP\",
    \"url\": \"https://${DOMAIN}\",
    \"type\": \"http\",
    \"interval_seconds\": 180,
    \"alert_contact_ids\": ${ALERT_CONTACT_IDS}
  }" | jq '{id, name}'

# 2. SSL certificate monitor
curl -s -X POST "${BASE_URL}/monitors" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d "{
    \"name\": \"[${DOMAIN}] SSL\",
    \"url\": \"https://${DOMAIN}\",
    \"type\": \"ssl\",
    \"interval_seconds\": 86400,
    \"ssl_expiry_alert_days\": 30
  }" | jq '{id, name}'

# 3. DNS monitor
curl -s -X POST "${BASE_URL}/monitors" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d "{
    \"name\": \"[${DOMAIN}] DNS\",
    \"url\": \"${DOMAIN}\",
    \"type\": \"dns\",
    \"interval_seconds\": 3600,
    \"alert_contact_ids\": ${ALERT_CONTACT_IDS}
  }" | jq '{id, name}'

echo "Monitors created for ${DOMAIN}"

The full eight-item pre-launch checklist is covered in "Pre-Launch Monitoring Checklist for Web Agencies." This guide focuses on the automation layer on top of that foundation.

Step 2: Verify HTTPS and Redirects Automatically

After creating monitors, run an automated script to confirm HTTPS access and HTTP-to-HTTPS redirect behavior.

#!/bin/bash
# verify_https.sh

DOMAIN="${CLIENT_DOMAIN}"

echo "=== HTTPS Verification: ${DOMAIN} ==="

# Confirm HTTPS returns 2xx or 3xx
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "https://${DOMAIN}")
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 400 ]; then
  echo "[OK] HTTPS response: ${HTTP_CODE}"
else
  echo "[FAIL] HTTPS response: ${HTTP_CODE} — needs investigation"
fi

# Confirm HTTP redirects to HTTPS
REDIRECT_URL=$(curl -s -o /dev/null -w "%{redirect_url}" "http://${DOMAIN}")
if echo "$REDIRECT_URL" | grep -q "https://"; then
  echo "[OK] HTTP redirect: ${REDIRECT_URL}"
else
  echo "[FAIL] No HTTP-to-HTTPS redirect — check Nginx/Apache config"
fi

# SSL certificate days remaining
EXPIRY_DATE=$(echo | openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:443" 2>/dev/null \
  | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
if [ -n "$EXPIRY_DATE" ]; then
  DAYS_LEFT=$(( ( $(date -d "$EXPIRY_DATE" +%s 2>/dev/null || gdate -d "$EXPIRY_DATE" +%s) - $(date +%s) ) / 86400 ))
  if [ "$DAYS_LEFT" -gt 30 ]; then
    echo "[OK] SSL expiry: ${DAYS_LEFT} days remaining"
  else
    echo "[WARN] SSL expiry: ${DAYS_LEFT} days — consider renewing soon"
  fi
fi

Step 3: Verify DNS Records Automatically

#!/bin/bash
# verify_dns.sh

DOMAIN="${CLIENT_DOMAIN}"
EXPECTED_IP="${EXPECTED_IP}"  # set to the correct server IP before running

echo "=== DNS Verification: ${DOMAIN} ==="

# Check A record
RESOLVED_IP=$(dig +short A "${DOMAIN}" | head -1)
if [ "$RESOLVED_IP" = "$EXPECTED_IP" ]; then
  echo "[OK] A record: ${RESOLVED_IP}"
else
  echo "[FAIL] A record: ${RESOLVED_IP} (expected: ${EXPECTED_IP}) — check DNS config"
fi

# Check TTL
TTL=$(dig +noall +answer A "${DOMAIN}" | awk '{print $2}' | head -1)
if [ -n "$TTL" ] && [ "$TTL" -le 300 ]; then
  echo "[OK] TTL: ${TTL}s (low TTL set)"
elif [ -n "$TTL" ]; then
  echo "[INFO] TTL: ${TTL}s — 300s recommended immediately before launch"
fi

# SPF record check
SPF_COUNT=$(dig +short TXT "${DOMAIN}" | grep -c "v=spf1")
if [ "$SPF_COUNT" -eq 1 ]; then
  echo "[OK] SPF record: 1 record found"
elif [ "$SPF_COUNT" -eq 0 ]; then
  echo "[WARN] SPF record: not found"
else
  echo "[FAIL] SPF record: ${SPF_COUNT} records (duplicate SPF breaks deliverability)"
fi

# DMARC record check
DMARC_RECORD=$(dig +short TXT "_dmarc.${DOMAIN}" | grep "v=DMARC1")
if [ -n "$DMARC_RECORD" ]; then
  echo "[OK] DMARC record: found"
else
  echo "[WARN] DMARC record: not found — may affect email deliverability"
fi

For detailed SPF, DKIM, DMARC, and MX record setup and ongoing monitoring, see "Setting Up and Continuously Monitoring SPF, DMARC, DKIM, and MX Records." A broken mail authentication record on launch day means contact form submissions go straight to spam — with no error visible on the site itself.

Step 4: Add Heartbeat Monitoring for Scheduled Jobs

Confirming the server responds is not enough. Scheduled jobs — backups, SSL auto-renewal, inventory syncs — can stop running silently after a launch, and active HTTP monitoring will never catch that. Heartbeat monitoring fills that gap.

# Add to crontab: run backup at 3 AM daily, ping Miterl only on success
0 3 * * * /path/to/backup.sh && curl -fsS https://miterl.com/heartbeat/YOUR_HEARTBEAT_TOKEN

For a full explanation of how heartbeat monitoring works and recommended interval settings, see "Heartbeat Monitoring: How to Verify Cron Jobs Are Running." Setting up heartbeat monitors at launch — rather than retroactively — means you are covered from day one.

Step 5: Wire Everything Into CI/CD

Combine these scripts into a single GitHub Actions workflow so the full pre-launch check runs on demand before any deployment.

# .github/workflows/pre-launch-check.yml
name: Pre-Launch Check

on:
  workflow_dispatch:
    inputs:
      client_domain:
        description: 'Domain to check'
        required: true
      expected_ip:
        description: 'Expected server IP'
        required: true

jobs:
  pre-launch:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Verify HTTPS
        env:
          CLIENT_DOMAIN: ${{ github.event.inputs.client_domain }}
        run: bash scripts/verify_https.sh

      - name: Verify DNS
        env:
          CLIENT_DOMAIN: ${{ github.event.inputs.client_domain }}
          EXPECTED_IP: ${{ github.event.inputs.expected_ip }}
        run: bash scripts/verify_dns.sh

      - name: Create Miterl Monitors
        env:
          CLIENT_DOMAIN: ${{ github.event.inputs.client_domain }}
          API_KEY: ${{ secrets.MITERL_API_KEY }}
        run: bash scripts/pre_launch_setup.sh

To extend this workflow with automatic rollback when a post-deployment check fails, see "Webhook Integration for Uptime Monitoring."

Step 6: Send Results to Slack

Route check results to a Slack channel so the whole team sees launch status in real time.

#!/bin/bash
# notify_slack.sh

WEBHOOK_URL="${SLACK_WEBHOOK_URL}"
DOMAIN="${CLIENT_DOMAIN}"
STATUS="${CHECK_STATUS:-OK}"

COLOR="good"
if [ "$STATUS" = "FAIL" ]; then COLOR="danger"; fi

curl -s -X POST "$WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d "{
    \"attachments\": [{
      \"color\": \"${COLOR}\",
      \"title\": \"Pre-Launch Check Complete: ${DOMAIN}\",
      \"text\": \"All automated checks have finished.\",
      \"fields\": [
        {\"title\": \"Status\", \"value\": \"${STATUS}\", \"short\": true},
        {\"title\": \"Domain\", \"value\": \"${DOMAIN}\", \"short\": true}
      ]
    }]
  }"

Step 7: Turn On Focused Monitoring the Moment You Deploy

Error rates are highest in the minutes right after a deploy, not in the days that follow — which is exactly when a normal check interval is too slow to catch a problem early. Release Mode (available on Standard and Pro plans) checks a monitor far more frequently than usual for a short window, then reverts to normal automatically.

Trigger it from the same CI/CD run as the pre-launch check, right after the deploy step, so nobody has to remember to click "Start" in the dashboard:

# Add as the final step after deploy succeeds
curl -X POST "https://miterl.com/api/v1/webhooks/release-mode/${RELEASE_WEBHOOK_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"duration_hours": 2, "interval_seconds": 60}'
  • The webhook token is per-monitor — find it on the monitor's detail page in the Miterl dashboard and store it as RELEASE_WEBHOOK_TOKEN in your CI secrets
  • duration_hours accepts 1–72 and interval_seconds accepts 15–300 at the API level; in practice, treat 60 seconds as the floor on Standard and 15 seconds on Pro to match what each plan is built for
  • If the monitor already has an active maintenance window, the trigger is blocked automatically so it doesn't collide with planned downtime
  • Free-plan monitors return 403 Release mode is not available on this plan — this step requires Standard or higher

Post-Launch Monitoring Window (First 24 Hours)

Once the automated checks pass and the site is live, plan for active monitoring during the first 24 hours:

  1. First hour: Confirm all monitors show "UP" in the Miterl dashboard
  2. First 8 hours: Watch for response time spikes or unexpected HTTP status codes
  3. First 24 hours: Confirm no overnight alerts fired and heartbeat pings arrived on schedule

If an incident does occur, the "Incident Response Playbook" walks through detection to post-mortem in a structured five-step format.

Frequently Asked Questions

Do I need the notify_slack.sh script, or does Miterl send Slack alerts natively?

They solve different problems. Miterl already sends monitor alerts — a site going down, an SSL certificate about to expire, and so on — directly to Slack once you add a Slack alert contact in the Miterl dashboard and attach its ID to the monitor's alert_contact_ids (the same IDs you looked up with GET /api/v1/alert-contacts in Step 1). No custom script is needed for that. The notify_slack.sh script in Step 6 solves a different problem: posting the pass/fail summary of your own pre-launch check script (Steps 2–4) to Slack, which is not a monitor alert and has no built-in Miterl equivalent.

What check interval should pre_launch_setup.sh use?

It depends on your plan. Free plans have a 300-second (5-minute) floor, Standard plans go down to 180 seconds, and Pro plans allow 60 seconds. The example script above creates the HTTP monitor with "interval_seconds": 180, which requires Standard or higher — on a Free plan, change it to 300 or the monitor creation request will fail validation.

Should I delete the monitors created by pre_launch_setup.sh after launch?

No, keep them. They are not throwaway pre-launch checks — once the site is live, the same HTTP, SSL, and DNS monitors become your ongoing uptime monitoring, with nothing to migrate or recreate.

Does Release Mode (Step 7) replace the checks earlier in this guide?

No, it complements them. Release Mode only increases how often an existing monitor is checked for a short window after deploy; it does not run HTTPS, DNS, or SPF/DMARC verification itself. Run the scripts in Steps 2–4 once for launch-day verification, then trigger Release Mode so the ongoing check catches anything that surfaces after the initial pass.

What happens if a heartbeat ping doesn't arrive after launch?

Miterl marks the heartbeat monitor Down once the configured interval (timeout) elapses without a signal, creates an incident, and alerts through whatever contacts are attached to that monitor — the same behavior as any other monitor type. See the heartbeat monitoring guide linked in Step 4 for how to size that interval for cron jobs and backups.

Summary

Pre-launch test automation lets web agencies ship confidently at any scale.

  • Scripting monitor creation, HTTPS checks, DNS verification, and SPF/DMARC validation removes the single-person dependency from every launch
  • Integrating into CI/CD means the checklist runs automatically every time, without anyone having to remember
  • Combining with heartbeat monitoring extends coverage to cron jobs and background tasks from day one
  • Slack notifications give the whole team real-time visibility into launch status
  • Triggering Release Mode from the same CI/CD run turns on focused post-deploy monitoring without a manual dashboard click

For detailed API documentation, see the documentation. Try the full setup by signing up for free. For examples of how agencies package monitoring into their maintenance offerings, see the use cases section.