
Automatiseer back-ups van Celigo-integraties naar GitHub met een shell-script.
Een praktische handleiding voor het exporteren van Celigo-integraties met behulp van de Celigo CLI — het uitpakken van exports in een versiebeheerde Git-repository, het automatisch maskeren van geheimen, en het op verzoek of volgens een schema een schone back-up naar GitHub pushen.
Categorie Celigo
Blog_field_Datum 15 april 2026
Het beheren van integraties over meerdere Celigo-omgevingen — of over klantaccounts — roept uiteindelijk een bekende vraag op: wanneer is deze flow voor het laatst gewijzigd, en wat was er vóór anders? Het Celigo-platform bewaart zijn eigen geschiedenis, maar het hebben van schone, versiegebonden exports in Git geeft je diffs, audit trails en een herstelbasis die buiten het platform leeft.
Deze gids bouwt een shell-gebaseerde workflow op met behulp van de Celigo CLI. Deze scripts exporteren de integraties die in de Celigo CLI voor elk geconfigureerd profiel downloadbaar zijn, pakken ze uit naar een consistente mapstructuur, redigeren vermoedelijk geheimen, en committen alleen wat is gewijzigd naar een private GitHub-repository.
Framing this correctly: This is a backup and versioning workflow, not a deployment pipeline. Celigo’s own guidance treats Git as a companion tool for backup, version history, and collaboration — the platform remains the source of truth for building and testing changes. If you need full environment promotion, pair this approach with Celigo ILM or a GitHub Actions pipeline using the REST API.
Wat deze setup doet
- De twee scripts behandelen de volledige export-naar-commit-cyclus:
- Maakt gebruik van de Celigo CLI met lokale profielen zodat API-tokens buiten Git blijven
- Exporteert de integraties die in de Celigo CLI voor elk geconfigureerd profiel downloadbaar zijn en pakt elk daarvan uit in een consistente account/omgeving/integratie-naam map
- Redigeert veelvoorkomende velden die op geheimen lijken uit geëxporteerde JSON-, YAML- en andere bestanden voordat iets wordt klaargezet
- Committeert alleen wat is gewijzigd en pusht naar jouw privé GitHub-repository
Voordat je begint
Je hebt het volgende nodig op de machine waarop de scripts draaien:
- Node.js en npm
- Git
- jq — voor JSON-verwerking
- unzip
- Python 3 — voor de redactiestap
- Een privé GitHub-repository
- Een Celigo API-token voor elke omgeving die je wilt back-uppen
Op macOS installeer je de shell-afhankelijkheden met:
Bashbrew install jq unzip
1. Installeer de Celigo CLI
Je kunt het Celigo npm-pakket hier downloaden:https://www.npmjs.com/package/@celigo/celigo-cli
Als wereldwijde npm-installaties mislukken met een machtigingsfout zodra je het pakket hebt, gebruik dan een Node-versiebeheerder zoals nvm in plaats van sudo te gebruiken.
2. Maak Celigo-profielen aan
Maak één profiel per Celigo-omgeving. De scripts verwachten profielen met namen in het formaat account-omgeving — zo wordt de mapstructuur automatisch afgeleid.
Bashceligo profile add client-prod --api-token YOUR_PROD_TOKEN --api-base-url https://api.eu.integrator.io celigo profile add client-sandbox --api-token YOUR_SANDBOX_TOKEN --api-base-url https://api.eu.integrator.io
Controleer vervolgens of uw profielen geregistreerd zijn:
Bashceligo profile list
De bovenstaande voorbeelden gebruiken het EU API-endpoint. Voor accounts in Noord-Amerika gebruik je in plaats daarvan de overeenkomende Noord-Amerikaanse basis-URL.
3. Stel de repository in
Kloon je privé GitHub-repository en maak een .gitignore aan om tijdelijke exportbestanden buiten versiebeheer te houden:
Bashgit clone https://github.com/YOUR_ORG/YOUR_REPO.git cd YOUR_REPO
Bash# .gitignore tmp_celigo_backup/ *.zip .DS_Store *.log
4. Voeg het export-script toe
Sla het volgende op als export_all_integrations.sh in de hoofdmap van je repository. Dit script regelt alle zware werkzaamheden: het ophalen van profielen, het downloaden van integraties als ZIP-bestanden, het uitpakken ervan en het uitvoeren van de redactie-fase.
Bash#!/usr/bin/env bash set -Eeuo pipefail BASE_DIR="${BASE_DIR:-./integrations}" TMP_DIR="${TMP_DIR:-./tmp_celigo_backup}" PROFILE_FILTER="${PROFILE_FILTER:-}" REDACT_EXPORTS="${REDACT_EXPORTS:-true}" require_cmd() { command -v "$1" >/dev/null 2>&1 || { echo "Missing required command: $1" >&2 exit 1 } } require_cmd celigo require_cmd jq require_cmd unzip require_cmd awk require_cmd sed require_cmd find require_cmd python3 mkdir -p "$BASE_DIR" "$TMP_DIR" cleanup() { rm -rf "$TMP_DIR" } trap cleanup EXIT sanitize_name() { printf '%s' "$1" \ | tr '[:upper:]' '[:lower:]' \ | sed 's/[[:space:]]\+/_/g' \ | sed 's|[/:]|-|g' \ | tr -cd '[:alnum:]_.-' } matches_filter() { local profile="$1" if [ -z "$PROFILE_FILTER" ]; then return 0 fi case "$profile" in *"$PROFILE_FILTER"*) return 0 ;; *) return 1 ;; esac } redact_file() { local file="$1" python3 - "$file" <<'PY' import json import pathlib import re import sys path = pathlib.Path(sys.argv[1]) text = path.read_text(encoding="utf-8", errors="ignore") SENSITIVE_KEYS = { "apiToken", "api_token", "token", "accessToken", "access_token", "refreshToken", "refresh_token", "clientSecret", "client_secret", "password", "pass", "secret", "consumerSecret", "consumer_secret", "privateKey", "private_key", "authorization", "authHeader", "signedURL", "signedUrl", "awsAccessKeyId", "accessKeyId", "accessKey", "secretAccessKey", "bearerToken", "jwt", "licenseKey" } KEY_PATTERN = re.compile( r'(?i)("?(?:api[_-]?token|token|access[_-]?token|refresh[_-]?token|client[_-]?secret|password|pass|secret|consumer[_-]?secret|private[_-]?key|authorization|auth[_-]?header|signedurl|awsaccesskeyid|access[_-]?key(?:id)?|secretaccesskey|bearer[_-]?token|jwt|license[_-]?key)"?\s*[:=]\s*)(".*?"|\'.*?\'|[^\s,}\]]+)' ) def redact(obj): if isinstance(obj, dict): out = {} for k, v in obj.items(): if k in SENSITIVE_KEYS or k.lower() in {s.lower() for s in SENSITIVE_KEYS}: out[k] = "__REDACTED__" else: out[k] = redact(v) return out if isinstance(obj, list): return [redact(v) for v in obj] return obj updated = text try: parsed = json.loads(text) redacted = redact(parsed) updated = json.dumps(redacted, indent=2, ensure_ascii=False) + " " except Exception: updated = KEY_PATTERN.sub(r'\1"__REDACTED__"', text) if updated != text: path.write_text(updated, encoding="utf-8") PY } redact_directory() { local dir="$1" find "$dir" -type f \( -name '*.json' -o -name '*.js' -o -name '*.ts' -o -name '*.yaml' -o -name '*.yml' \ -o -name '*.txt' -o -name '*.env' -o -name '*.properties' -o -name '*.xml' \) -print0 | while IFS= read -r -d '' file; do redact_file "$file" done find "$dir" -type f \( -name '.env' -o -name '.npmrc' -o -name '*.pem' -o -name '*.key' -o -name '*.p12' -o -name '*.crt' \) -delete } echo "Fetching Celigo profiles..." PROFILE_LINES="$(celigo profile list || true)" if [ -z "$PROFILE_LINES" ]; then echo "No Celigo profiles found." exit 1 fi PROFILE_NAMES=() while IFS= read -r line; do PROFILE_NAME="$(printf '%s' "$line" | awk 'NF {print $1}')" case "$PROFILE_NAME" in ""|NAME|Name|PROFILE|Profile) continue ;; esac if [ -n "$PROFILE_NAME" ] && matches_filter "$PROFILE_NAME"; then PROFILE_NAMES+=("$PROFILE_NAME") fi done <<< "$PROFILE_LINES" if [ ${#PROFILE_NAMES[@]} -eq 0 ]; then echo "No matching Celigo profiles found." exit 1 fi echo "Profiles selected:" for PROFILE_NAME in "${PROFILE_NAMES[@]}"; do echo " - $PROFILE_NAME" done for PROFILE_NAME in "${PROFILE_NAMES[@]}"; do if [[ "$PROFILE_NAME" != *-* ]]; then echo "Skipping '$PROFILE_NAME' — profile name must follow account-environment format." continue fi ACCOUNT_NAME="${PROFILE_NAME%%-*}" ENV_NAME="${PROFILE_NAME#*-}" SAFE_ACCOUNT="$(sanitize_name "$ACCOUNT_NAME")" SAFE_ENV="$(sanitize_name "$ENV_NAME")" ACCOUNT_DIR="$BASE_DIR/$SAFE_ACCOUNT" ENV_DIR="$ACCOUNT_DIR/$SAFE_ENV" TMP_JSON="$TMP_DIR/${SAFE_ACCOUNT}_${SAFE_ENV}_integrations.json" mkdir -p "$ENV_DIR" echo "Fetching integrations for $PROFILE_NAME..." celigo --profile "$PROFILE_NAME" integrations list --format json > "$TMP_JSON" if [ ! -s "$TMP_JSON" ]; then echo "No output returned for $PROFILE_NAME" rm -f "$TMP_JSON" continue fi COUNT="$(jq 'length' "$TMP_JSON")" echo "Found $COUNT integrations in $PROFILE_NAME" if [ "$COUNT" -eq 0 ]; then rm -f "$TMP_JSON" continue fi while IFS= read -r row; do ID="$(printf '%s' "$row" | jq -r '._id')" NAME="$(printf '%s' "$row" | jq -r '.name // .title // ._id')" SAFE_NAME="$(sanitize_name "$NAME")" TARGET_DIR="$ENV_DIR/$SAFE_NAME" ZIP_PATH="$TMP_DIR/${SAFE_ACCOUNT}_${SAFE_ENV}_${SAFE_NAME}.zip" echo " Downloading: $NAME" celigo --profile "$PROFILE_NAME" integrations download "$ID" -o "$ZIP_PATH" rm -rf "$TARGET_DIR" mkdir -p "$TARGET_DIR" unzip -oq "$ZIP_PATH" -d "$TARGET_DIR" rm -f "$ZIP_PATH" if [ "$REDACT_EXPORTS" = "true" ]; then redact_directory "$TARGET_DIR" fi done < <(jq -c '.[]' "$TMP_JSON") rm -f "$TMP_JSON" done echo "" echo "Export complete. Output: $BASE_DIR"
Maak het uitvoerbaar:
Bashchmod +x export_all_integrations.sh
5. Voeg het Git-push-script toe
Sla dit op als backup_to_git.sh in dezelfde map. Het roept het export-script aan, controleert op wijzigingen en duwt een met tijdstempel gemaakte commit naar de repository:
Bash#!/usr/bin/env bash set -Eeuo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" EXPORT_SCRIPT="$ROOT_DIR/export_all_integrations.sh" if [ ! -f "$EXPORT_SCRIPT" ]; then echo "export_all_integrations.sh not found alongside this script." >&2 exit 1 fi if ! git -C "$ROOT_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then echo "Not a Git repository: $ROOT_DIR" >&2 exit 1 fi echo "Running Celigo export from: $ROOT_DIR" "$EXPORT_SCRIPT" cd "$ROOT_DIR" git add integrations/ .gitignore export_all_integrations.sh backup_to_git.sh 2>/dev/null || true COMMIT_MSG="Backup Celigo integrations $(date +%Y-%m-%d_%H-%M)" if git diff --cached --quiet; then echo "No changes since last backup." exit 0 fi git commit -m "$COMMIT_MSG" CURRENT_BRANCH="$(git branch --show-current)" if [ -z "$CURRENT_BRANCH" ]; then CURRENT_BRANCH="main" fi echo "Pushing to GitHub (branch: $CURRENT_BRANCH)..." git push origin "$CURRENT_BRANCH" echo "Backup complete."
Maak het uitvoerbaar:
Bashchmod +x backup_to_git.sh
6. Voer de back-up uit
Bash./backup_to_git.sh
De eerste uitvoering committeert alle integraties. Aardige voltrekkende? Nee. Subsecente runs committen alleen wat is gewijzigd — zodat je Git-log een duidelijk verschil geeft van precies wat er is gewijzigd tussen back-ups.
Om te filteren op een specifiek account zonder het script aan te passen, stel de PROFILE_FILTER-variabele in tijdens de uitvoering:
BashPROFILE_FILTER=client ./backup_to_git.sh
Resulterende mapstructuur
Na een succesvolle uitvoering ziet jouw repository er als volgt uit:
Textintegrations/ client/ prod/ order-to-cash/ export.json ... inventory-sync/ ... sandbox/ order-to-cash/ ... export_all_integrations.sh backup_to_git.sh .gitignore
Elke integratie krijgt zijn eigen map met de naam die is afgeleid van het velden-van-de-integratie-naam, opgeschoond tot lowercase met underscores. Het toevoegen van een nieuw profiel maakt automatisch de juiste account- en omgevingsmappen aan bij de volgende uitvoering.
Beveiligingsoverwegingen
De redactie-stap dekt de meest voorkomende gevallen — API-tokens, client secrets, wachtwoorden, private keys, bearer tokens, ondertekende URLs — in zowel JSON-parsbare bestanden als platte tekst backups via regex. Een paar aanvullende gewoontes die het waard zijn om te blijven volgen:
- Houd de back-upopslag privé. Zelfs met redactie kan exported integratiestructuur en flow-logica bedrijfslogica en syste-architectuur blootleggen.
- Sla API-tokens alleen op in lokale CLI-profielen, nooit in omgevingsvariabelen die gelogd kunnen worden of in scripts die gecommit worden.
- Loop een diff na voordat je een repository openbaar maakt. De redactie-logica is breed maar niet uitputtend — aangepaste veldnamen voor geheimen worden niet automatisch opgevangen.
- Behandel certificaat- en sleutelbestanden als buiten scope. Het script verwijdert .pem, .key, .p12 en .crt bestanden uit de exportdirectory — controleer of deze worden opgeruimd als ze in jouw exports voorkomen.
Beperkingen waarmee je rekening moet houden
Deze workflow is uitstekend geschikt voor back-up, wijzigingsbeoordeling en versiegeschiedenis. Het vervangt geen volledige deployment-pijplijn. Enkele specifics om in gedachten te houden:
- Deze workflow is bedoeld voor integraties die jouw Celigo-account en CLI alsZIP-bestanden kan downloaden. Integratie-apps worden anders afgehandeld en kunnen andere tooling of clone-workflows vereisen.
- Na het importeren in een andere omgeving, beoordeel verbindingen, referenties en omgevingsspecifieke instellingen zorgvuldig in plaats van aan te nemen dat ze probleemloos worden overgezet. De documentatie van Celigo is op dit punt niet volledig consistent, dus een handmatige controle is de veiligste veronderstelling.
- Deze workflow vervangt Celigo ILM niet voor gestructureerde omgevingspromotie. Als je integraties verplaatst van sandbox naar productie op een gecontroleerde, herhaalbare manier, is ILM het juiste gereedschap.
Draaien op Windows
Het betreft Bash-scripts — ze maken gebruik van functies zoals here-docs, process substitution en chmod +x die niet native werken in CMD of PowerShell. Op Windows kun je ze uitvoeren via een van deze twee setups:
- Git Bash — inbegrepen bij Git for Windows, biedt Bash-emulatie die het volledige script ondersteunt.
- WSL (Windows Subsystem for Linux) — draait een volledig GNU/Linux-omgeving rechtstreeks op Windows. Installeer Node, jq en de andere dependencies binnen de WSL-distributie.
Als je geleidelijke uitvoeringen op Windows wilt, gebruik Taakplanner om het script in Git Bash of WSL te activeren, in plaats van cron.
Perspectief vanuit de praktijk
De meest voorkomende reden waarom teams dit soort opzet zoeken, is een incident: een flow is gewijzigd, er is iets stuk gegaan, en de vraag is wat er anders was. Het hebben van versiegebonden exports in Git betekent dat die vraag een antwoord heeft — en het antwoord vereist geen duiken in platform-auditlogs of iemand vragen wat ze vorige week denken gewijzigd te hebben.
Dit draaien op een cron-schema (dagelijks of na significante wijzigings-vensters) biedt een lichtgewicht maar effectief wijzigingsdagboek. Het vervangt niet de eigen geschiedenis van het Celigo-platform, maar het is een formaat dat je kunt doorzoeken, diffen en aan een ontwikkelaar kunt geven zonder toegang tot het platform te geven.
Als je hulp wilt bij het opzetten van een meer complete Celigo-versionering- of deployment-pijplijn — inclusief ILM, GitHub Actions of multi-omgevingsbeheer — neem contact op. Als gecertificeerde Celigo-partner kan Teknuro je helpen het te ontwerpen en bouwen.


