Naar de hoofdinhoud

Deployment-omgevingen

Omgevingen zijn benoemde deploymentdoelen (bijv. staging, production, eu-west) met combineerbare veiligheidspoorten. Een workflowjob die environment: production declareert, wordt tegen ALLE ingestelde poorten getoetst voordat fremforge de runner-VM inricht. Faalt er een poort, dan wordt de deploy geweigerd met een gestructureerde reden. Beheerders van de organisatie beoordelen dat in de beheeromgeving; de workflow kan opnieuw worden gestart zodra de onderliggende situatie is opgelost.

Snel aan de slag

  1. Ga naar Organisatiebeheer → Omgevingen (https://frem.sh/<org>/_admin/environments).

  2. Vul onder Nieuwe omgeving een naam in en klik op Aanmaken.

  3. Open de detailpagina van de nieuwe omgeving, scrol naar Uitrolbeleid, stel het gewenste beleid in en klik op Beleid opslaan.

  4. Verwijs in een willekeurige workflowjob naar de omgeving:

    jobs:
      deploy:
        runs-on: fremforge
        environment: production
        steps:
          - run: ./deploy.sh

De volgende deploy naar deze omgeving wordt tegen je poorten getoetst.

De 9 poorten

Alle poorten zijn onafhankelijk en combineerbaar. ALLE ingestelde poorten moeten SLAGEN voordat een deploy doorgaat. Een poort zonder instellingen wordt overgeslagen (geldt als geslaagd).

A. Verplichte goedkeurders

Houd het starten tegen totdat N mensen op Goedkeuren hebben geklikt bij de openstaande deploy.

  • Wanneer gebruiken: productiedeploys, gereguleerde omgevingen, alles waarbij een tweede paar ogen het vangnet is.
  • Instellen: Vereiste reviewers op de detailpagina van de omgeving. 0 = geen goedkeuring; 1–6 = N goedkeurders vereist.
  • Waar goedkeuren: Organisatiebeheer → Deployments (/<org>/_admin/deployments), sectie “Openstaande goedkeuringen”.
  • Let op: de gebruiker die de workflow in gang zette (de persoon die de commit pushte of de PR opende) kan zijn eigen deploy niet goedkeuren. Het platform weigert zelfgoedkeuring zowel in de routelaag als in de evaluator.
  • Intrekken: goedkeurders kunnen hun eigen goedkeuring intrekken zolang de deploy nog niet is gestart (bijv. als je na het klikken op Goedkeuren een probleem ontdekte). Is de deploy eenmaal gestart, dan staat de goedkeuring vast.

B. Toegestane refs (branch- / tagpatronen)

Beperk welke Git-refs naar deze omgeving mogen deployen.

  • Wanneer gebruiken: “alleen main deployt naar productie”; “alleen tags release/* deployen naar canary”.
  • Instellen: Branches en tags voor uitrol op de detailpagina van de omgeving. Globs in GitHub-stijl: main, release/*, **/hotfix-*, refs/tags/v[0-9]+.*. Leeg = elke ref toegestaan.

C. Tijdvenster

Beperk deploys tot bepaalde kantooruren of blokkeer ze tijdens een bevriezing.

  • Wanneer gebruiken: “deploys alleen ma–do 09:00–17:00 CET”; “blokkeer alle deploys van 22 dec t/m 2 jan (bevriezing tijdens de feestdagen)”.

  • Instellen: JSON voor het tijdvenster op de detailpagina van de omgeving. Vorm:

    {
      "tz": "Europe/Copenhagen",
      "allowed": [
        { "days": ["Mon", "Tue", "Wed", "Thu"], "from": "09:00", "to": "17:00" }
      ],
      "blackouts": [
        { "from": "2026-12-22T00:00Z", "to": "2027-01-02T00:00Z", "reason": "holiday freeze" }
      ]
    }
    • tz: IANA-tijdzone. Standaard UTC.
    • allowed: lijst met toegestane vensters. Dagen hebben 3 letters (Mon..Sun). Tijden zijn in 24-uursnotatie HH:MM in tz.
    • blackouts: lijst met absolute UTC-periodes waarin deploys verboden zijn, ongeacht allowed.
  • Let op: blackouts gaan vóór allowed. Leeg = geen tijdsbeperking.

D. Gezond SLO-budget

Weiger deploys zolang het foutbudget van de SLO wordt opgebrand.

  • Wanneer gebruiken: “deploy niet terwijl de latency of het foutpercentage voor klanten in het rood staat; los eerst de regressie op.”
  • Instellen: Blokkeren wanneer deze alarmen afgaan: door komma’s gescheiden namen van CES/LTS-alarmen die je burn-rate-watchdogs bijhouden. Voorbeeld: my-api-latency-sev1, my-api-error-budget-sev2.
  • Hoe het werkt: fremforge houdt de laatste status van elk vermeld alarm bij. Staat een van de vermelde alarmen op firing, dan weigert deze poort het starten.
  • Faalt dicht: heeft fremforge geen recente status voor een vermeld alarm, dan faalt de poort dicht; onderzoek gaat voor ongemerkt omzeilen.

E. Verplichte statuschecks

Eis dat benoemde commitstatuscontexten van Forgejo op de commit die wordt gedeployd success zijn.

  • Wanneer gebruiken: “deploys moeten wachten tot dep-scan, SAST en image-scan op deze commit allemaal slagen.”
  • Instellen: Verplichte checkcontexten: één per regel. Voorbeelden: dep-scan, sast, sha-pin-scan, image-scan-trivy.
  • Hoe het werkt: fremforge leest bij de voorcontrole GET /api/v1/repos/<o>/<r>/statuses/<sha>. Elke verplichte context moet de status success hebben. Ontbrekende statussen OF statussen die geen succes zijn, laten de poort falen.

F. Gelijktijdigheidsslot

Begrens het aantal lopende deploys naar deze omgeving.

  • Wanneer gebruiken: “maar één productiedeploy tegelijk”; voorkomt racecondities waarbij twee deploys elkaar overschrijven.
  • Instellen: Maximaal aantal lopende deploys: geheel getal 0–100. 0 = geen limiet.
  • Telt mee: de statussen pending_gates, pending_approval en dispatched. Een poging met completed of failed telt niet meer mee.

G. Afkoelperiode na een rollback

Blokkeer na een rollback N minuten lang deploys, zodat het team kan onderzoeken wat er misging.

  • Wanneer gebruiken: “dwing na een rollback een pauze van 60 minuten af voordat er opnieuw wordt gedeployd”; voorkomt dat dezelfde regressie per ongeluk opnieuw wordt uitgerold.
  • Instellen: Afkoelperiode na rollback (minuten): geheel getal 0–1440 (24 uur). 0 = geen afkoelperiode.

H. Gekoppeld ticket verplicht

Eis dat de tekst van de PR die wordt gedeployd naar een issue- of incidentticket verwijst.

  • Wanneer gebruiken: eis vanuit compliance of audittrail: aan elke productiedeploy moet een “waarom” hangen.
  • Instellen: vink Een ticketverwijzing in de PR-tekst vereisen aan. Optioneel overschrijf je het ticketpatroon met een eigen regex.
  • Standaardpatroon: (?i)(JIRA|FF|INC|FIX)-[0-9]+|fixes? #[0-9]+|closes? #[0-9]+|resolves? #[0-9]+; komt overeen met JIRA-1234, FF-99, fixes #42, Closes #99, enz. Het voorvoegsel (?i) maakt het hoofdletterongevoelig.
  • Eigen patroon per organisatie: elke geldige JavaScript-regex. Het voorvoegsel (?i) wordt gerespecteerd.

I. Pauzevlag

Een schakelaar per omgeving die alle deploys stillegt.

  • Wanneer gebruiken: tijdens een incident. Zet een pauze; onderzoek; hef de pauze op.
  • Instellen: Per omgeving (organisatiebeheer): <org>/_admin/deployments → sectie “Pauzevlaggen”. fremforge kan tijdens een incident ook een pauze voor het hele platform instellen; elke actieve pauze die je omgeving dekt, blokkeert de deploy.
  • Afhandeling: voor het redenveld wint het meest specifieke bereik, maar ELK actief bereik blokkeert de deploy.

Zo verloopt een evaluatie

Wanneer het platform een workflow met environment: <name> oppakt:

  1. Voorcontrole: fremforge zoekt de omgeving van de organisatie op. Geen omgeving ingesteld = er gelden geen poorten (geleidelijke onboarding; workflows van nieuwe klanten worden niet geblokkeerd voordat ze omgevingen hebben ingesteld).
  2. Een deploypoging aanmaken of opzoeken met als sleutel (env, ref, commit_sha). Wordt dezelfde workflow opnieuw gestart voor dezelfde commit, dan delen die runs dezelfde poging, zodat een goedkeuringsstroom over nieuwe pogingen heen blijft gelden.
  3. Gegevens ophalen: het e-mailadres van de actor en de tekst van de PR worden uit Forgejo gelezen. Naar beste vermogen; bij een verstoring van Forgejo wordt teruggevallen op synthetische waarden.
  4. Alle 9 poorten parallel evalueren: elke poort is onafhankelijk en leest zijn eigen signaal.
  5. Samenstellen: slagen ALLE ingestelde poorten, dan gaat de status naar dispatched en wordt de runner-VM ingericht. Faalt ALLEEN poort A (goedkeurders), dan gaat de status naar pending_approval; beheerders kunnen op Goedkeuren klikken en de volgende poging evalueert opnieuw. Faalt een andere poort, dan gaat de status naar gates_failed.
  6. Audit: het volledige overzicht van de poortresultaten wordt vastgelegd en er wordt een auditevent verstuurd.

Hoe een geweigerde deploy eruitziet

De klant ziet: een geannuleerde workflowrun, met een commitstatuscheck die de reden van de weigering toont (bijv. deploy_gate_C_time_window — outside allowed windows).

De beheerder van de organisatie ziet: een regel bij de openstaande deployments met het volledige overzicht van de evaluatie: welke poorten slaagden, welke faalden, met per poort de specifieke reason-tekst.

Wat er in elke omgeving live staat

Organisatiebeheer → Deployments (https://frem.sh/<org>/_admin/deployments) begint met Live per omgeving. Voor elke omgeving zie je de deploy die nu live staat en de deploy daarvoor, je doel voor een rollback:

  • de repository, de ref (branch of tag) en de commit, met link;
  • de tags die naar die commit wijzen, bijvoorbeeld prd-2026-11-01 of rc-81;
  • wie hem heeft goedgekeurd, en wanneer;
  • wanneer de deploy klaar was, en een link naar de workflow-run.

Een deploy telt alleen als live wanneer de run is gestart en is geslaagd. Mislukte, geannuleerde, geweigerde en nog wachtende pogingen tellen nooit mee, dus na een mislukte deploy blijft de vorige als live staan. Een omgeving zonder geslaagde deploy toont Nooit gedeployed.

Releasetooling leest dezelfde gegevens via de API, met een token met deployments:read, zonder de pagina uit te lezen:

curl -fsS "https://frem.sh/_app/api/v1/orgs/acme/deployments/live?environment=production" \
  -H "Authorization: Bearer $FREMFORGE_TOKEN"

Elke omgeving in het antwoord heeft live en previous, allebei null zolang er niets is gedeployed. Elk bevat repo_full_name, ref, commit_sha, commit_url, tags, approvals, deployed_at, run_number en run_url. Laat ?environment= weg om alle omgevingen te krijgen. tags komt uit de 150 nieuwste tags van de repository en kan tot een minuut oud zijn. Het veld is null (niet []) als de tags op dat moment niet gelezen konden worden.

Poorten combineren

De ladder is bewust combineerbaar: de meeste klanten stellen 2–3 poorten per omgeving in, niet alle 9. Voorgestelde startpunten:

PatroonIngestelde poortenReden
Solo-ontwikkelaar, één omgevinggeenBij een eenmansteam zijn geen poorten nodig; fremforge staat standaard op “alle branches toegestaan”.
Klein team, productieomgevingB (refs=main) + I (pauzevlag beschikbaar)Voorkomt dat featurebranches per ongeluk naar productie gaan; de on-call heeft de noodschakelaar.
Middelgroot team, gereguleerdA (2 reviewers) + B (refs=main, release/*) + H (gekoppeld ticket) + IGoedkeuring + audittrail + noodschakelaar over teams heen.
Enterprise, meerdere fasenA (3 reviewers) + B + C (kantooruren) + D (gezonde SLO) + E (dep-scan + sast) + F (gelijktijdigheid=1) + G (afkoelperiode van 60 min) + H + IDe volledige ladder; op deze schaal is elke poort zinvol.

Begin klein en voeg poorten toe naarmate je groeit.

Secrets en variabelen per omgeving

Los van de poorten hebben omgevingen hun eigen secrets en variabelen, die alleen worden geïnjecteerd in jobs die environment: <name> declareren. Zie Secrets voor de werkwijze met secrets.

Omgevingen beheren via de API

Alles wat de beheeromgeving doet, kan ook via de REST API. Omgevingen staan in de namespace fremforge-extension, dus de basis-URL is https://frem.sh/_app/api/v1, niet het kale /api/v1: dat is de eigen API van Forgejo en die weigert de aanroep.

MethodePadScope
GET/orgs/<org>/environmentsenvironments:read
POST/orgs/<org>/environmentsenvironments:write
GET/orgs/<org>/environments/<name>environments:read
DELETE/orgs/<org>/environments/<name>environments:write
PUT DELETE/orgs/<org>/environments/<name>/variables/<VAR>environments:write
GET/orgs/<org>/environments/<name>/secretsenvironments:read
PUT/orgs/<org>/environments/<name>/secrets/<NAME>environments:write
DELETE/orgs/<org>/environments/<name>/secrets/<id>environments:write
PUT/orgs/<org>/environments/<name>/gatesenvironments:write
PUT/orgs/<org>/environments/<name>/branchesenvironments:write
GET/orgs/<org>/deployments/livedeployments:read

Namen van omgevingen voldoen aan [A-Za-z0-9_.-]+ (geen /). Namen van variabelen voldoen aan [A-Z][A-Z0-9_]*, met waarden tot 64 KiB. Waarden van secrets worden at rest versleuteld en nooit teruggegeven: de lijst-endpoints geven alleen namen en metadata.

# Create an environment, then give it a variable and a secret.
curl -fsS -X POST https://frem.sh/_app/api/v1/orgs/acme/environments \
  -H "Authorization: Bearer $FREMFORGE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"name":"staging"}'

curl -fsS -X PUT https://frem.sh/_app/api/v1/orgs/acme/environments/staging/variables/REGION \
  -H "Authorization: Bearer $FREMFORGE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"value":"eu-de"}'

curl -fsS -X PUT https://frem.sh/_app/api/v1/orgs/acme/environments/staging/secrets/DEPLOY_KEY \
  -H "Authorization: Bearer $FREMFORGE_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"value":"…"}'
Over de naam van het veld in de body. Variabelen en secrets van een omgeving gebruiken {"value": "…"}. Secrets op organisatieniveau (PUT /orgs/<org>/secrets/<NAME>) zijn gedocumenteerd als {"data": "…"} en accepteren value ook als alias, dus beide spellingen werken. Stuur je beide mee, dan wint data.

Als je een 403 krijgt

403 Token lacks required scope 'environments:…' betekent dat het endpoint bestaat en dat je token de scope niet heeft; het is geen ontbrekende functie. Controleer welke scopes je inloggegevens werkelijk hebben. Een PAT die je zelf hebt aangemaakt, heeft precies de scopes die je hebt aangevinkt; een dev-bench heeft een door het platform uitgegeven set die bewust beperkter is en wordt vernieuwd wanneer de bench ontwaakt.

OIDC-claim voor de omgeving

Workflows die environment: <name> declareren, krijgen een extra OIDC-claim: sub wordt repo:<owner>/<repo>:environment:<name>. Daarop matchen de vertrouwensbeleidsregels van cloudproviders bij kortlevende federatie (AWS STS AssumeRoleWithWebIdentity, Azure WIF, GCP Workload Identity Federation). Zie OIDC-federatie voor de vormen van het vertrouwensbeleid.

Problemen oplossen

De workflow blijft hangen op “Review pending” en er is geen melding verstuurd. → Controleer het aantal vereiste reviewers van de omgeving. Goedkeuren gebeurt op de beheerpagina met openstaande deployments; fremforge mailt reviewers (nog) niet. Neem de pagina op in de ochtendstand-up van je team.

Een deploy werd geweigerd met deploy_gate_D_slo_burn, maar ik heb poort D niet ingesteld. → Poort D faalt dicht als fremforge geen recente status heeft voor een vermeld alarm. Heb je de naam van een alarm VERMELD dat nog nooit een status heeft gemeld, dan weigert de poort automatisch. Haal de alarmnaam uit de instellingen van de poort, of zorg dat het alarm zo is ingericht dat de status wordt gemeld.

De tekst van de PR komt overeen met een ticketpatroon, maar poort H faalt toch. → De deploypoging is aangemaakt VOORDAT de PR werd geopend. fremforge legt de tekst van de PR vast bij de eerste evaluatie en haalt die niet opnieuw op. Push een lege commit om een nieuwe evaluatie te starten.

Ik wil de poorten tijdelijk omzeilen. → Er is nog geen interface om per organisatie te omzeilen. Neem contact op met support@frem.sh om een poort tijdelijk te laten omzeilen. De pauzevlaggen kun je alleen aan- en uitzetten.

Auditevents

Elke beslissing van een poort verstuurt gestructureerde auditevents:

EventWanneer
environment.gates.updateBeheerder van de organisatie wijzigt de instellingen van een poort
tenant.deploy.approval_grantedGoedkeurder klikt op Goedkeuren
tenant.deploy.approval_rejectedGoedkeurder klikt op Afwijzen (met reden)
tenant.deploy.approval_revokedGoedkeurder trekt de eigen goedkeuring in
tenant.deploy.pause_set / _clearedPauzevlag per omgeving omgezet (organisatiebeheer)
platform.deploy.pause_set / _clearedPauzevlag voor het hele platform omgezet