The 06:00 workflow is now one schedule-trigger -> Execute Command pair that runs scripts/morning-brief.sh on the host over a restricted SSH key. The earlier scan -> HTTP shape could not work: the n8n container cannot resolve the `remote` ssh alias (its ~/.ssh/config is a dangling nix symlink) and a split scan node hides scan failures before the notify node runs. - deploy/n8n-morning-brief.json: two-node workflow, scheduleTrigger v1.3 - deploy/setup-n8n-scan-key.sh: restricted (restrict,command=) trigger key - deploy/import-n8n-morning-brief.sh: import + publish + restart + verify - deploy/DEPLOYMENT.md, Makefile: document and expose both scripts (dry run) - docs/phase-7a-n8n-schedule.md: design, verification, failure drill Import into the shared n8n service still needs Sam's approval. Co-Authored-By: Paperclip <noreply@paperclip.ing>
102 lines
3.1 KiB
Bash
Executable File
102 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Phase 7a (AUD-115): import + publish the 6:00am workflow in n8n.
|
|
#
|
|
# n8n on .13 is a shared family service. Run this only after the change is
|
|
# approved. It imports one workflow, publishes it, restarts n8n once so the
|
|
# 06:00 schedule registers, and verifies the published state.
|
|
#
|
|
# It does NOT run the workflow. The first real run is the next 06:00 trigger
|
|
# (or `docker exec n8n n8n execute --id=<id>` by hand).
|
|
#
|
|
# Usage:
|
|
# deploy/import-n8n-morning-brief.sh # dry run, print the plan
|
|
# deploy/import-n8n-morning-brief.sh --apply
|
|
# deploy/import-n8n-morning-brief.sh --apply --no-restart
|
|
#
|
|
# Environment overrides:
|
|
# CONTAINER n8n container name (default n8n)
|
|
# WORKFLOW workflow json path (default <repo>/deploy/n8n-morning-brief.json)
|
|
set -euo pipefail
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
CONTAINER="${CONTAINER:-n8n}"
|
|
WORKFLOW="${WORKFLOW:-$REPO_ROOT/deploy/n8n-morning-brief.json}"
|
|
IN_CONTAINER="/tmp/n8n-morning-brief.json"
|
|
|
|
APPLY=0
|
|
RESTART=1
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--apply) APPLY=1 ;;
|
|
--no-restart) RESTART=0 ;;
|
|
-h|--help) sed -n '2,20p' "$0"; exit 0 ;;
|
|
*) echo "unknown argument: $arg" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
[[ -f "$WORKFLOW" ]] || { echo "workflow not found: $WORKFLOW" >&2; exit 1; }
|
|
|
|
# The workflow name is stable; match on a substring to survive em-dash changes.
|
|
WF_MATCH="${WF_MATCH:-6:00am morning brief}"
|
|
|
|
n8n_cli() { docker exec "$CONTAINER" n8n "$@"; }
|
|
|
|
wf_id() {
|
|
n8n_cli list:workflow 2>/dev/null \
|
|
| awk -F'|' -v m="$WF_MATCH" 'index($2, m) { print $1; exit }'
|
|
}
|
|
|
|
echo "workflow file : $WORKFLOW"
|
|
echo "n8n container : $CONTAINER"
|
|
echo "in-container : $IN_CONTAINER"
|
|
echo "restart n8n : $([[ "$RESTART" -eq 1 ]] && echo yes || echo no)"
|
|
|
|
if [[ "$APPLY" -eq 0 ]]; then
|
|
echo
|
|
echo "DRY RUN — no change to n8n. Re-run with --apply."
|
|
echo "steps:"
|
|
echo " 1. copy the JSON into the container"
|
|
echo " 2. n8n import:workflow"
|
|
echo " 3. n8n publish:workflow --id=<id>"
|
|
echo " 4. $([[ "$RESTART" -eq 1 ]] && echo 'docker restart n8n (≈10s)' || echo 'skip restart')"
|
|
echo " 5. n8n list:workflow --active=true shows the workflow"
|
|
exit 0
|
|
fi
|
|
|
|
echo
|
|
echo "== 1. copy the workflow into the container =="
|
|
docker exec -i "$CONTAINER" sh -c "cat > $IN_CONTAINER" < "$WORKFLOW"
|
|
|
|
echo "== 2. import =="
|
|
n8n_cli import:workflow --input="$IN_CONTAINER"
|
|
|
|
ID="$(wf_id)"
|
|
if [[ -z "$ID" ]]; then
|
|
echo "could not find the imported workflow by name '$WF_MATCH'" >&2
|
|
n8n_cli list:workflow >&2 || true
|
|
exit 1
|
|
fi
|
|
echo "workflow id: $ID"
|
|
|
|
echo "== 3. publish =="
|
|
n8n_cli publish:workflow --id="$ID"
|
|
|
|
echo "== 4. restart =="
|
|
if [[ "$RESTART" -eq 1 ]]; then
|
|
docker restart "$CONTAINER" >/dev/null
|
|
echo "n8n restarted; waiting for the API to answer…"
|
|
for _ in $(seq 1 30); do
|
|
if curl -s -o /dev/null --max-time 3 "http://127.0.0.1:5678/healthz"; then
|
|
echo "n8n is up"
|
|
break
|
|
fi
|
|
sleep 2
|
|
done
|
|
fi
|
|
|
|
echo "== 5. verify =="
|
|
n8n_cli list:workflow --active=true
|
|
echo
|
|
echo "AUTHORIZED_KEY_HINT: the Execute Command node calls the host with"
|
|
echo " ~/.ssh/id_ed25519_school_scan — create it with deploy/setup-n8n-scan-key.sh --apply"
|