Phase 7a: real 6:00am n8n schedule for the school brief (AUD-115)
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>
This commit is contained in:
101
deploy/import-n8n-morning-brief.sh
Executable file
101
deploy/import-n8n-morning-brief.sh
Executable file
@@ -0,0 +1,101 @@
|
||||
#!/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"
|
||||
Reference in New Issue
Block a user