Naar artikels

Versiebeheer voor HubSpot: één repository voor Design Manager, projecten en workflow actions

CategorieGids
Gepubliceerd17 sep 2026

Rechtstreeks in de portal werken is het probleem

HubSpot laat je een module, een template of een workflow action rechtstreeks in de UI aanpassen, en voor één wijziging voelt dat sneller dan eender welk alternatief. Dat gevoel verdwijnt de eerste keer dat twee mensen dezelfde module aanpassen in dezelfde week, of iemand vraagt wat er vorige dinsdag veranderd is en waarom. Er is geen diff, geen review, geen branch, en geen weg terug behalve onthouden wat er in het bestand stond. Alles hieronder bestaat om dat werk te verplaatsen naar een plek waar die vier dingen gratis zijn.

Eén repository, geen drie

Een portal wordt meestal behandeld als verschillende losse werelden: Design Manager-assets aan de ene kant, projecten met hun private apps en serverless functions aan de andere, workflow actions ergens nog elders. Ze staan niet los van elkaar. Een wijziging aan een template vraagt vaak een wijziging aan de functie die hem voedt, en die splitsen over repositories betekent dat één stuk werk binnenkomt als twee pull requests die in de juiste volgorde gemerged moeten worden. Eén repository per portal, met een map per onderdeel, houdt een wijziging reviewbaar als één geheel.

Twee deploy-mechanismen die op elkaar lijken en het niet zijn

Hier loopt het bij de meeste setups mis, want de CLI biedt twee commando's die gelijkaardig klinken en zich totaal anders gedragen. Design Manager-content wordt gepusht met één upload-commando met een bron en een bestemming. Project-backends gaan via het Projects-framework, dat helemaal geen bron- of bestemmingsargumenten heeft: het draait tegen de huidige werkmap, dus een pipeline moet eerst naar de projectmap wisselen.

# Design Manager-content: bron -> Design Manager-pad
hs cms upload "design-manager/my-module" "My Module" --account <portal>

# Project-backend: geen src/dest, draait tegen de werkmap
cd projects/<name>/app
hs project upload --account <portal>

De commando's die niet bestaan

Zoek op hoe je HubSpot-assets deployt en je vindt posts die hs upload en hs template upload gebruiken. Geen van beide is een bestaand commando. Ze waren het ooit, de posts zijn nooit bijgewerkt, en de fout die je terugkrijgt vertelt je niet dat je advies leest uit een andere generatie van de CLI. Voor je een pipeline bouwt op een commando dat je online gevonden hebt: check het tegen de CLI die je effectief geïnstalleerd hebt, niet tegen een zoekresultaat.

# toon wat je geïnstalleerde CLI echt ondersteunt
hs --help
hs cms --help
hs project --help

Projecten deployen in twee stappen

Een project uploaden zet niets live. Het maakt een build: een verpakte kandidaat die in de portal wacht om gepromoveerd te worden. Die build deployen is een apart commando, en in CI heeft het de vlag nodig die het non-interactief maakt, anders hangt de pipeline op een prompt die niemand gaat beantwoorden. Upload als de deploy-stap beschouwen is de meest voorkomende reden waarom een pipeline succes meldt terwijl de portal exact blijft zoals hij was.

hs project upload --account <portal>                           # maakt een build
hs project deploy --deploy-latest-build -f --account <portal>  # promoveert hem

Je mapnamen zijn niet van jou

Het upload-commando mapt een lokaal pad rechtstreeks op een Design Manager-pad, wat betekent dat je repository-boom de portal exact moet spiegelen. Een map die je lokaal hernoemt omdat het beter leest, hernoemt niets in HubSpot; het maakt een tweede map naast de originele en laat de live versie stilletjes ongemoeid. Eerst spiegelen, nooit opkuisen. Als de naamgeving in de portal slecht is, fix je dat in de portal en volgt de repository.

Een branch per omgeving

Het punt van dit alles is niet de repository, maar de flow die ze mogelijk maakt: werken tegen een sandbox-portal tot het klopt, en dan promoveren. Een branch gekoppeld aan de sandbox en een branch gekoppeld aan productie geeft je dat zonder plichtplegingen. Mergen in de eerste deployt naar de sandbox, mergen in de tweede gaat live, en het verschil tussen beide branches is een leesbare lijst van alles wat nog moet vertrekken.

staging  ->  sandbox-portal
main     ->  productie-portal

Deploy alleen wat veranderd is

Een portal-repository verzamelt snel deploybare onderdelen, en elke upload draaien bij elke push maakt van een wijziging van één regel een lange pipeline die assets aanraakt die niemand bewerkt heeft. De meeste CI-systemen kunnen een stap laten afhangen van welke paden in de push veranderd zijn. Geef elke deploybare map zijn eigen stap met zijn eigen padvoorwaarde, en een wijziging aan één module deployt één module.

Authenticatie zonder secrets te committen

De CLI verwacht een configbestand met een access token, en de verleiding is om dat te committen zodat de pipeline het vindt. Doe dat niet. Genereer het tijdens de build uit beveiligde CI-variabelen, gebruik het, en verwijder het in dezelfde stap, met de bestandsnaam in gitignore zodat een toevallige lokale kopie niet mee kan liften. Wees hier streng in: een configbestand met een geldige token in een map die nooit een git-repository was, is prima tot de dag dat iemand daar git init draait, en tegen dan zit de token in de historiek in plaats van in een bestand dat je kan wissen.

Wat je weglaat

De Design Manager-root bevat ook HubSpots eigen standaardassets en alles wat uit de marketplace geïnstalleerd is. Dat is vendor-code, beheerd door wie ze uitbrengt, en ze inchecken betekent dat elke update binnenkomt als een diff die je niet geschreven hebt en niet zinvol kan reviewen. De redenering is dezelfde die een dependency-map buiten een applicatie-repository houdt: volg wat je zelf schrijft, niet wat je installeert.

Wat je er echt aan hebt

Niets hiervan maakt één deploy sneller dan op opslaan klikken in de portal. Wat het oplevert is alles eromheen: een review voor een wijziging productie bereikt, een historiek die antwoordt wie wat veranderd heeft en waarom, een rollback die een revert is in plaats van een opgravingsoefening, en een sandbox die een repetitie is in plaats van een hoopvolle gok. Op een portal die één persoon af en toe aanraakt is dat overhead. Op een portal waar een team van afhangt, is het het verschil tussen een platform en een gedeeld document dat iedereen bang is aan te passen.

Laten we iets bouwen dat werkt, en je bedrijf laten groeien.

Neem contact op