Zum Hauptinhalt springen

Einsatz in der CI

Eine typische Pipeline validiert und testet jede Änderung offline, rendert Vorschauen der geänderten Vorlagen für das Review und veröffentlicht auf dem Standard-Branch.

GitHub Actions​

Die Action Formfeed templates (formfeed-dev/formfeed-action) führt diese Schritte für Sie aus:

name: templates
on:
pull_request:
paths: ['templates/**', 'partials/**']
push:
branches: [main]
paths: ['templates/**', 'partials/**']

jobs:
templates:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write # für den Vorschau-Kommentar
steps:
- uses: actions/checkout@v4
- uses: formfeed-dev/formfeed-action@v1
with:
api-key: ${{ secrets.FORMFEED_TEST_KEY }}

- if: github.event_name == 'push'
uses: formfeed-dev/formfeed-action@v1
with:
api-key: ${{ secrets.FORMFEED_LIVE_KEY }}
validate: false
test: false
publish: true

Jeder Lauf validiert und testet die Vorlagen offline. Bei einem Pull Request mit API-Schlüssel rendert die Action die Vorlagen, die der Pull Request ändert, lädt sie als Artefakt formfeed-preview hoch und schreibt die Zusammenfassung als einen Kommentar, den jeder Lauf aktualisiert; ein Pull Request aus einem Fork läuft ohne Ihre Secrets und überspringt die Vorschau. Mit publish: true pusht sie die Vorlagen und veröffentlicht sie, oder pusht sie mit channel in einen Release Channel. Sie führt die veröffentlichte Kommandozeile formfeed in der Version aus, die ihre Eingabe version nennt; jede Eingabe steht unter GitHub Actions.

Ohne die Action​

Dieselben Schritte ausgeschrieben, für einen Workflow, der sie selbst anordnet:

name: templates
on:
pull_request:
paths: ['templates/**', 'partials/**']
push:
branches: [main]
paths: ['templates/**', 'partials/**']

jobs:
templates:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write # nur für den Pull-Request-Kommentar unten
env:
FORMFEED_API_KEY: ${{ secrets.FORMFEED_TEST_KEY }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # ci preview vergleicht mit dem Basis-Branch
- uses: actions/setup-node@v4
with: { node-version: 22 }

- run: npx formfeed validate --ci
- run: npx formfeed test --ci

- if: github.event_name == 'pull_request'
run: npx formfeed ci preview --base origin/${{ github.base_ref }} --ci
- if: github.event_name == 'pull_request'
uses: actions/upload-artifact@v4
with:
name: formfeed-preview
path: |
formfeed-preview/
formfeed-preview.md

- if: github.event_name == 'push'
run: npx formfeed templates push --publish --message "${{ github.sha }}" --ci
env:
FORMFEED_API_KEY: ${{ secrets.FORMFEED_LIVE_KEY }}

validate und test laufen offline und brauchen keinen Schlüssel; nur ci preview und templates push rufen die API auf.

Was ci preview tut​

formfeed ci preview rendert die seit --base geänderten Vorlagen über die API:

  • Welche Vorlagen. Es fragt git nach den Dateien, die sich zwischen --base und HEAD geändert haben (git diff --name-only <base>...HEAD), und nimmt jeden Vorlagenordner mit einer geänderten Datei. Eine geänderte Datei im Partials-Ordner rendert alle Vorlagen, weil jede sie einbinden kann. --all rendert alle Vorlagen. Kann git nicht antworten, weil es fehlt oder die Basis-Ref unbekannt ist (ein flacher Clone), werden ebenfalls alle Vorlagen gerendert; holen Sie den Basis-Branch also vorher.
  • Was es rendert. Jede Vorlage einmal, mit ihrem Standard-Datensatz (data/default.json, sonst die erste Datei in data/), in ihrem Standardformat. HTML-Vorlagen werden im Job gerendert und als HTML an die API gesendet; die Vorschau zeigt also die Dateien des Branches, keine hochgeladene Version. Word- und PowerPoint-Vorlagen werden im Job gefüllt und über die API in PDF umgewandelt, was den Starter-Plan oder höher braucht.
  • Was es schreibt. Eine Datei je Vorlage nach formfeed-preview/ (<slug>.pdf oder das Bildformat) und eine Markdown-Zusammenfassung nach formfeed-preview.md: eine Tabelle mit Vorlage, Datensatz, Seitenzahl und einem Link auf die gerenderte Datei oder dem Grund, aus dem eine Vorlage scheiterte. Die Links sind die Download-Links der Renderings und laufen mit der Ausgabe ab, bei einem Test-Schlüssel nach höchstens einem Tag. Ohne Änderungen rendert es nichts, und die Zusammenfassung sagt das.
  • Optionen. --base <ref> (Standard origin/main), --out <dir> (Standard formfeed-preview), --summary <file> (Standard formfeed-preview.md), --all.
  • Exit-Code. 1, wenn mindestens ein Rendering als fehlgeschlagen endete oder sich eine Word- oder PowerPoint-Vorlage nicht füllen ließ; die Zusammenfassung nennt sie. Ein Rendering, das die API sofort ablehnt (ein Problem wie 422 page_limit_exceeded), beendet den Befehl mit dem Exit-Code dieses Problems, bevor die Zusammenfassung geschrieben ist.

Der Schlüssel braucht render:create und render:read, dazu file:read, wenn Vorlagen Dateien der Dateibibliothek mit asset() zeigen: Damit liest die CLI die Adresse der Bibliothek, und ohne ihn fehlen diese Bilder in der Vorschau. Renderings mit einem Test-Schlüssel sind kostenlos. Posten Sie die Zusammenfassung mit einer beliebigen Kommentar-Action als Pull-Request-Kommentar, zum Beispiel:

- if: github.event_name == 'pull_request'
run: gh pr comment ${{ github.event.number }} --body-file formfeed-preview.md --edit-last || gh pr comment ${{ github.event.number }} --body-file formfeed-preview.md
env:
GH_TOKEN: ${{ github.token }}

GitLab CI​

templates:
image: node:22
variables:
GIT_DEPTH: 0
script:
- npx formfeed validate --ci
- npx formfeed test --ci
- git fetch origin "$CI_DEFAULT_BRANCH" # ein Job checkt nur seinen eigenen Branch aus
- npx formfeed ci preview --base origin/$CI_DEFAULT_BRANCH --ci
artifacts:
paths: [formfeed-preview/, formfeed-preview.md]

publish-templates:
image: node:22
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
- FORMFEED_API_KEY=$FORMFEED_LIVE_KEY npx formfeed templates push --publish --message "$CI_COMMIT_SHA" --ci

Legen Sie FORMFEED_API_KEY (einen Test-Schlüssel) und FORMFEED_LIVE_KEY als maskierte CI/CD-Variablen an.

Empfehlungen​

  • Nutzen Sie einen Test-Schlüssel für Vorschauen; seine Renderings sind kostenlos, seine Dateien werden nach einem Tag gelöscht. Geben Sie diesem Schlüssel kein template:write, damit ein Pull Request keine Vorlagen ändern kann, sondern nur dem Schlüssel des Veröffentlichungsschritts auf dem Standard-Branch. Vorlagen sind für Test- und Live-Schlüssel dieselben, also kann jede Art von Schlüssel veröffentlichen; die Beispiele verwenden dort einen Live-Schlüssel.
  • Halten Sie Datensätze in data/*.json, die die Randfälle abdecken: leere Listen, sehr lange Namen, fehlende optionale Felder, hundert Positionen. test rendert jeden davon; validate prüft jede Vorlage gegen ihren Standard-Datensatz (--data <name> wählt einen anderen), bei E-Rechnungsvorlagen den _invoice-Block jedes Datensatzes und bei Vorlagen, die pdf.ua festlegen, was schon die Quelle zeigt. Nur Fehler lassen einen Schritt scheitern; Warnungen wie unknown-variable (eine Variable, die in den Daten fehlt) werden ausgegeben und gehen durch.
  • Legen Sie formfeed validate in einen Pre-Commit-Hook, um sofort Rückmeldung zu bekommen.
  • Committen Sie die erzeugten Typen und führen Sie npx formfeed types --check --ci in der Pipeline aus, damit eine Schema- oder Datenänderung ohne neu erzeugte Typen den Build scheitern lässt. Siehe Typisierte Vorlagendaten.
  • templates push --publish legt von jedem Vorlagenordner, den ignore nicht auslässt, eine neue Version an und veröffentlicht sie, ob er sich geändert hat oder nicht; nennen Sie eine Vorlage (templates push invoice --publish), um nur diese zu veröffentlichen. Committen Sie .formfeed/state.json nicht, wenn die CI veröffentlicht: Die CI committet den Stand, den sie festhält, nicht zurück, also ist der committete nach der ersten Veröffentlichung veraltet, und der nächste Push damit wird mit 409 conflict beantwortet (Exit-Code 2), bis jemand erneut zieht oder mit --force pusht.
  • Wer bei jedem Merge veröffentlicht, schaltet jede Änderung sofort live. Um vorher zu testen, pushen Sie stattdessen in einen Channel (templates push --channel staging) und veröffentlichen in einem eigenen Schritt; siehe Release Channels.
  • Legen Sie die CLI-Version in Ihrer package.json fest (npm install -D formfeed), damit CI und Laptops übereinstimmen.
  • Skripte können sich auf die Exit-Codes und auf die Ausgabe von --json verlassen.