Naar de hoofdinhoud

Actions en CI/CD

fremforge draait Forgejo Actions, een CI/CD-systeem dat compatibel is met GitHub Actions. Workflowbestanden gebruiken de YAML-syntaxis van GitHub Actions, en ongeveer 95% van de actions uit de GitHub Marketplace werkt zonder aanpassingen.

Locatie van workflowbestanden

Zet workflowbestanden in .forgejo/workflows/<name>.yaml in je repository. Voor compatibiliteit met repository’s die vanaf GitHub zijn gemigreerd, leest Forgejo ook .github/workflows/, maar .forgejo/workflows/ is op fremforge de standaardlocatie.

Trigger-events

EventTrigger
pushElke push naar overeenkomende branches of tags
pull_requestPR geopend, gesynchroniseerd of heropend
pull_request_targetPR tegen de doelrepository (voor forks); zie de beveiligingsopmerking hieronder
scheduleCron-schema (UTC)
workflow_dispatchHandmatige trigger vanuit de interface of de API
workflow_callHerbruikbare workflow die door een andere workflow wordt aangeroepen
releaseRelease gepubliceerd, aangemaakt of bewerkt
issuesIssue geopend, bewerkt, gesloten of gelabeld
issue_commentOpmerking bij een issue of PR
createBranch of tag aangemaakt
deleteBranch of tag verwijderd
registry_packagePakket gepubliceerd of bijgewerkt

Contextvariabelen

fremforge gebruikt contextnamen github.* voor compatibiliteit met het GitHub Actions-ecosysteem. Ze verwijzen naar de fremforge/Forgejo-instantie, niet naar GitHub.

VariabeleWaarde
github.actorGebruikersnaam van de gebruiker die de run startte
github.repository<org>/<repo>
github.refVolledige Git-ref, bijv. refs/heads/main
github.shaSHA van de commit
github.event_nameEvent dat de workflow startte
github.run_idUnieke identificatie van de run
github.server_urlhttps://frem.sh
github.api_urlhttps://frem.sh/api/v1

Ingebouwde secrets

SecretBeschrijving
secrets.FORGEJO_TOKENAutomatisch gegenereerd token per job; beperkt tot de repository; standaard alleen-lezen, behalve dat het de pakketten van de repository kan publiceren
secrets.GITHUB_TOKENAlias voor FORGEJO_TOKEN (compatibiliteit)

Ingebouwde tokens zijn kortlevend en beperkt tot de huidige workflowrun. Ze kunnen niet buiten de job worden gebruikt die ze ontving.

Het permissions-blok

De standaardset rechten is contents: read. Alle andere rechten staan standaard op none, tenzij ze expliciet worden gedeclareerd.

permissions:
  contents: read       # git checkout
  id-token: write      # OIDC token federation
  issues: write        # create / update issues
  pull-requests: write # comment on PRs

Declareer rechten op workflowniveau (geldt voor alle jobs) of op het niveau van een afzonderlijke job. Declaraties op jobniveau gaan vóór die op workflowniveau.

packages: write staat niet in deze lijst, omdat het niet nodig is. Het ingebouwde token per job leest al elk pakket van de eigenaar van de repository en schrijft pakketten die aan de eigen repository zijn gekoppeld (runs van pull requests uit forks alleen lezen). Zie Publiceren vanuit Forgejo Actions.

Minimaal workflowvoorbeeld

name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: fremforge
    steps:
      - uses: actions/checkout@v4
      - name: Run tests
        run: npm ci && npm test

Herbruikbare workflows

Breng gemeenschappelijke logica onder in een herbruikbare workflow die andere workflows met workflow_call aanroepen:

# .forgejo/workflows/reusable.yaml
on:
  workflow_call:
    inputs:
      environment:
        required: true
        type: string

jobs:
  deploy:
    runs-on: fremforge
    environment: ${{ inputs.environment }}
    steps:
      - run: echo "Deploying to ${{ inputs.environment }}"

Roep hem aan vanuit een andere workflow:

jobs:
  deploy-staging:
    uses: ./.forgejo/workflows/reusable.yaml@main
    with:
      environment: staging

Caching

Gebruik actions/cache om mappen tussen runs te bewaren:

- uses: actions/cache@v3
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-

Cachehits maken jobs voor pakketbeheerders, buildtools en gecompileerde uitvoer aanzienlijk sneller. De ingebouwde caching van actions/setup-node, setup-python, setup-go en setup-java (cache: npm enzovoort) gebruikt dezelfde dienst.

Zo gedraagt de cache zich op fremforge:

  • Beperkt tot de repository. Een cache die in de ene repository is opgeslagen, is nooit zichtbaar voor een andere, in dezelfde organisatie of een andere. Binnen een repository delen branches één cache.
  • Pull requests zijn geïsoleerd. Een pull_request-run kan de caches van de repository herstellen, maar wat hij opslaat is alleen zichtbaar voor latere runs van dezelfde pull request, zodat een pull request (ook een uit een fork) niet kan veranderen wat andere branches herstellen.
  • Limieten. Tot 10 GiB per item en 10 GiB per repository; gaat een repository daarboven, dan worden de minst recent gebruikte items verwijderd. Items die 7 dagen niet zijn gebruikt of ouder zijn dan 30 dagen, worden verwijderd.
  • Laat nooit een job falen. Is de cache niet beschikbaar, dan logt actions/cache een waarschuwing en gaat de job zonder cache verder.

De cache wordt opgeslagen op de eigen infrastructuur van fremforge in de EU.

Omgevingen en deploymentpoorten

Omgevingen voegen goedkeuringspoorten, verplichte reviewers en secrets per omgeving toe aan deployjobs.

Maak omgevingen aan onder Organisatiebeheer → Omgevingen (https://frem.sh/<org>/_admin/environments). Stel verplichte reviewers in om handmatige goedkeuring te eisen voordat de job draait.

Verwijs in een job naar een omgeving:

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

Heeft production verplichte reviewers, dan wacht de job op goedkeuring voordat hij wordt uitgevoerd. Secrets die op de omgeving production zijn ingesteld, worden alleen in deze job geïnjecteerd.

Opmerkingen over compatibiliteit

  • ~95% van de actions uit de GitHub Marketplace werkt zonder aanpassingen.
  • secrets.GITHUB_TOKEN is een alias voor secrets.FORGEJO_TOKEN. Actions die het gebruiken, werken zoals ze zijn.
  • Actions die de GitHub-API rechtstreeks aanroepen (hardgecodeerd api.github.com), falen. De API-URL van fremforge is https://frem.sh/api/v1.
  • Actions die openbare gegevens lezen van api.github.com (de versielijsten van de setup-*-actions, downloads van releases) delen de limiet van GitHub van 60 verzoeken per uur met elke job op hetzelfde uitgaande IP-adres. Pin een major.minor-versie en geef een GitHub.com-token mee: zie Rate limit van de GitHub-API.
  • actions/upload-artifact en actions/download-artifact werken.
  • GitHub Packages (ghcr.io, pkg.github.com) is niet beschikbaar. Gebruik in plaats daarvan het pakketregister van fremforge.
  • Actions die GitHub-specifieke functies vereisen (GitHub Copilot, GitHub Codespaces, GitHub Packages), hebben geen equivalent in fremforge.
  • De workflowcommando’s ::set-output, ::set-env en ::add-path doen niets. Schrijf in plaats daarvan naar $GITHUB_OUTPUT, $GITHUB_ENV en $GITHUB_PATH; zie Outputs, omgevingsvariabelen en PATH.
  • Een expressie die niet kan worden geëvalueerd, laat haar stap of job falen, en dat geldt ook voor een ongeldige strategy.matrix, zoals een exclude die een waarde noemt die de matrix niet heeft.
  • Jobsamenvattingen worden niet ondersteund. Een stap die naar $GITHUB_STEP_SUMMARY schrijft, slaagt nog steeds, maar de samenvatting wordt weggegooid en het log van de stap toont de waarschuwing This Forgejo instance does not support job summaries.

Zie Marketplace-compatibiliteit voor de volledige compatibiliteitsmatrix van de top-100 actions.

Outputs, omgevingsvariabelen en PATH

Sinds 21 oktober 2026 draaien de gehoste runners forgejo-runner 13, waarin drie workflowcommando’s zijn verwijderd: ::set-output, ::set-env en ::add-path. Een stap die een daarvan print, krijgt een waarschuwing in zijn log en gaat verder door, maar de output, omgevingsvariabele of PATH-vermelding wordt niet gezet. De job kan nog steeds groen worden, waarna een latere stap of job een lege waarde leest.

Dit speelt vooral bij workflows die vanaf GitHub zijn overgezet, waar ::set-output verouderd is maar nog wordt geaccepteerd. ACTIONS_ALLOW_UNSECURE_COMMANDS=true zetten brengt de commando’s niet terug.

Schrijf in plaats daarvan naar de bestanden die de runner aanwijst. Elk is beschikbaar als GITHUB_* en als FORGEJO_*, en beide wijzen naar hetzelfde bestand, zodat een workflow die ook op GitHub draait met de GITHUB_*-namen blijft werken.

Verwijderd commandoSchrijf in plaats daarvan naar
echo "::set-output name=NAME::value"echo "NAME=value" >> "$GITHUB_OUTPUT" (of $FORGEJO_OUTPUT)
echo "::set-env name=NAME::value"echo "NAME=value" >> "$GITHUB_ENV" (of $FORGEJO_ENV)
echo "::add-path::/some/dir"echo "/some/dir" >> "$GITHUB_PATH" (of $FORGEJO_PATH)

Vroeger, wat nu niets meer zet:

      - id: version
        run: echo "::set-output name=tag::$(git describe --tags)"
      - run: echo "Releasing ${{ steps.version.outputs.tag }}"   # empty

Nu:

      - id: version
        run: echo "tag=$(git describe --tags)" >> "$GITHUB_OUTPUT"
      - run: echo "Releasing ${{ steps.version.outputs.tag }}"

Zo vind je de commando’s in een repository: git grep -nE '::(set-output|set-env|add-path)'. Een Marketplace-action die ze nog print, verliest zijn outputs op dezelfde manier; werk hem bij naar een release die naar de bestanden schrijft.

Bereik van secrets bij PR’s uit forks: beleid voor pull_request_target

Kort gezegd: workflows die door pull_request_target worden gestart, draaien met de secrets en rechten van de doelrepository, ook als de PR uit een fork komt. Check in zo’n workflow nooit de head van de PR uit en draai die nooit (bijvoorbeeld actions/checkout met ref: ${{ github.event.pull_request.head.sha }}): dan draait onbetrouwbare code naast je secrets. Gebruik pull_request om bijdragen te bouwen en te testen; PR’s uit forks draaien daar zonder secrets en zonder identiteitstoken.

pull_request_target draait workflows in de context van de doelrepository wanneer een PR uit een fork komt. De workflow heeft dan dus toegang tot de secrets van de doelrepository, ook al kan het workflowbestand door de auteur van de fork zijn aangepast. Dit is precies de aanvalsvorm achter de klasse van het incident met de GitHub Actions Marketplace in 2023.

Beleid van fremforge: workflows die pull_request_target gebruiken, MOGEN GEEN code uit de fork uitvoeren terwijl er secrets aanwezig zijn. Twee aanvaardbare patronen:

  1. pull_request in plaats van pull_request_target als de workflow code uit de fork moet draaien. De workflow van de PR uit de fork draait in de context van de fork; secrets van de doelrepository zijn niet bereikbaar. Dit is de standaard en de veilige vorm.
  2. pull_request_target ALLEEN voor alleen-lezen workflows voor labelen, triage of opmerkingen die expliciet github.sha uitchecken (de merge-base, niet de head van de fork) en geen stap voor installeren, bouwen of testen uit de fork draaien.

Workflows die pull_request_target combineren met actions/checkout@v4 op github.event.pull_request.head.sha, zijn een SEV-1-vector voor het weglekken van secrets en worden bij de review vóór de merge gemarkeerd. Een pre-receive-hook in Forgejo die de gevaarlijke combinatie statisch weigert, staat op de roadmap voor verdere versterking; tot die er is, is de codereview de actieve poort.

Geen omgeving voor een run uit een fork (strenger dan GitHub). Een pull_request_target-run die door een pull request uit een fork wordt gestart, krijgt helemaal geen omgeving: geen secrets van een omgeving, geen variabelen van een omgeving en geen environment-claim in zijn OIDC-token, ook niet als de job environment: declareert en het workflowbestand van de basis wordt uitgevoerd. GitHub geeft zo’n run de omgeving wel, onder voorbehoud van de beschermingsregels ervan; fremforge doet dat sinds 2026-10-27 niet. Pull requests vanuit een branch van dezelfde repository houden hun omgeving, gelezen uit het workflowbestand van de basisbranch en zoals gebruikelijk bewaakt door de branchregel en reviewers van de omgeving. De branchregel wordt, net als op GitHub, gecontroleerd tegen de basisbranch waarop de pull request is gericht, niet tegen de eigen ref van de pull request (refs/pull/<n>/head): een omgeving die tot main is beperkt, laat een pull_request_target-job uit dezelfde repository toe op een pull request naar main. Secrets van de repository en de organisatie blijven ongewijzigd: een pull_request_target-run van een fork krijgt die nog steeds, net als op GitHub en Forgejo.

Daarom blijft het uitchecken van de head gevaarlijk. Een pull_request_target-job die de head-code van de pull request uitcheckt en draait (een installatie, een build, een test, een script uit de PR), geeft die code elk secret dat de job nog kan bereiken: de secrets van de repository en de organisatie, en het jobtoken. Het achterhouden van de omgeving verandert daar niets aan. Houd zulke jobs bij de alleen-lezen vorm hierboven, of verplaats het werk naar pull_request.

Geen OIDC-id-token voor een run uit een fork. Een pull_request_target-run die door een pull request uit een fork wordt gestart, krijgt geen id-token: getIDToken (of id-token: write) antwoordt met 403, wat de audience ook is. Zo’n run kan dus niet naar een cloud federeren of sleutelloos ondertekenen met Sigstore. Een job die moet deployen of ondertekenen, hoort bij push of workflow_dispatch, nadat een maintainer de wijziging heeft gemerged. Runs vanuit de repository zelf, ook pull requests vanuit een branch van dezelfde repository, worden niet geraakt.

Volledige achtergrond: het beveiligingsmodel van Forgejo Actions is hetzelfde als dat van GitHub. De semantiek van pull_request_target is overgenomen, behalve dat fremforge aan een run uit een fork geen id-token en geen omgeving geeft.

Beleid voor imagebronnen

uses:-regels hebben twee vormen. Beide worden op fremforge geaccepteerd, maar de egress verschilt:

  • uses: <owner>/<repo>@<sha>: wordt opgelost tegen de EU-mirror voor actions op frem.sh/<owner>/<repo>. Elke upstream-uitgever heeft zijn eigen mirror-organisatie (actions, docker, aws-actions, azure, google-github-actions, peter-evans, softprops, sonarsource, step-security, dorny, pnpm), dus uses: actions/checkout@<sha> wordt frem.sh/actions/checkout. Mirrors synchroniseren elke 8 uur met upstream. Dit is de aanbevolen vorm.
  • uses: docker://<registry>/<image>:<tag>: Forgejo Actions lost dit op door de image rechtstreeks op te halen bij de registry-URL die de auteur van de workflow opgaf. Er is geen automatische omleiding naar een fremforge-mirror, en op dit moment geen ingebouwde allowlist voor het registrydeel. Zet vast op een digest (docker://<registry>/<image>@sha256:…) in plaats van een veranderlijke tag. Sinds 2026-10-24 toont de dagelijkse scan Workflow-pinning elke docker://-verwijzing die niet op een digest is vastgezet. Een pre-receive-hook in Forgejo of een allowlist aan runnerzijde voor docker:// staat op de roadmap voor verdere versterking; behandel een niet-vastgezette docker://-verwijzing tot die er is als een punt voor de codereview.

De API voor workflowruns

Er bestaan vier routes en ze werken alle vier. Alleen de eerste twee staan ergens anders gedocumenteerd, en daarom worden de andere twee meestal als ontbrekend gemeld:

WatRoute
Runs opvragenGET /api/v1/repos/<owner>/<repo>/actions/runs
Logs ophalenGET /api/v1/repos/<owner>/<repo>/actions/runs/<run_id>/logs
Een run annulerenPOST /api/v1/repos/<owner>/<repo>/actions/runs/<run_id>/cancel
Een run opnieuw startenPOST /api/v1/repos/<owner>/<repo>/actions/runs/<run_id>/rerun
# stop a run that is queued or in progress
curl -X POST -H "Authorization: token <forgejo-pat>" \
  https://frem.sh/api/v1/repos/<owner>/<repo>/actions/runs/<run_id>/cancel
# -> 204, and the run's status becomes `cancelled`

Waarom annuleren lijkt niet te bestaan

Elk signaal wijst ervan weg, dus “ik kon het niet vinden” is de te verwachten uitkomst en geen teken van slecht zoeken:

  • DELETE geeft 405. De route is alleen POST. DELETE .../cancel en beide werkwoorden op .../runs/<id> (zonder /cancel) geven allemaal 405.
  • /actions/tasks/<id>/cancel geeft 404. Taken zijn geen runs.
  • De eigen OpenAPI-specificatie van Forgejo wordt hier niet aangeboden. /swagger.v1.json en elke variant daarvan geven op frem.sh 404, dus er is niets om de route in op te zoeken.
  • De API-specificatie van fremforge beschrijft hem niet, en kan dat ook niet. Die documenteert de endpoints van dit platform, niet die van Forgejo: cancel komt er alleen in voor onder /orgs/{org}/billing/cancel, en dat gaat over abonnementen. Wie daarin zoekt naar een manier om een run te annuleren, vindt de verkeerde cancel.
  • De fremforge-API antwoordt met 501. Dat is het vangnet voor /api/v1/*-paden die met geen enkel endpoint overeenkomen, en de melding verwijst naar de OpenAPI-specificatie van fremforge, dus terug naar de specificatie die deze route niet bevat.
  • ffp_*-tokens kunnen het helemaal niet. De proxy op organisatieniveau overbrugt alleen de logs-route (zie hieronder); annuleren en opnieuw starten vereisen een Forgejo-PAT of sessiecookie.

Als je runs vaker dan eens met de hand annuleert

Schrijf er geen script voor; stel in plaats daarvan een concurrency-groep in, zodat Forgejo de achterhaalde run zelf annuleert:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

Elke push naar een branch vervangt dan de vorige run van die branch. Veilig voor verplichte checks: statussen gelden per commit, dus het annuleren van de run voor een oudere commit kan de checks van de huidige head niet laten hangen.

Een geannuleerde run laat zijn checks falen. De commitstatus van elke geannuleerde job eindigt op failure met de beschrijving Has been cancelled, of de job nu draaide of nog wachtte. Annuleer je dus een run op de commit die je wilt mergen, dan worden de verplichte checks rood en zal een ingeschakelde automatische merge niet doorgaan. Push opnieuw, of POST .../rerun.

Workflows in- en uitschakelen

De knoppen Workflow uitschakelen / Workflow inschakelen op het tabblad Actions van een repository hebben API-equivalenten. De paden, operatienamen en JSON zijn die van Gitea, dus een client die voor de API van Gitea is geschreven, werkt ongewijzigd.

WatRouteWie
Workflows en hun status opvragenGET /api/v1/repos/<owner>/<repo>/actions/workflowsiedereen die de Actions van de repository mag lezen
Eén workflow ophalenGET /api/v1/repos/<owner>/<repo>/actions/workflows/<workflow_id>iedereen die de Actions van de repository mag lezen
Een workflow uitschakelenPUT /api/v1/repos/<owner>/<repo>/actions/workflows/<workflow_id>/disablebeheerder van de repository, met een token
Een workflow inschakelenPUT /api/v1/repos/<owner>/<repo>/actions/workflows/<workflow_id>/enablebeheerder van de repository, met een token

<workflow_id> is de bestandsnaam van de workflow, bijv. ci.yaml, zoals die in .forgejo/workflows/ (of .gitea/workflows/, .github/workflows/) op de standaardbranch staat.

# switch a workflow off, then back on
curl -X PUT -H "Authorization: token <forgejo-pat>" \
  https://frem.sh/api/v1/repos/<owner>/<repo>/actions/workflows/ci.yaml/disable
# -> 204
curl -X PUT -H "Authorization: token <forgejo-pat>" \
  https://frem.sh/api/v1/repos/<owner>/<repo>/actions/workflows/ci.yaml/enable
# -> 204

# which workflows are switched off?
curl -H "Authorization: token <forgejo-pat>" \
  https://frem.sh/api/v1/repos/<owner>/<repo>/actions/workflows
{
  "workflows": [
    {
      "id": "ci.yaml",
      "name": "CI",
      "path": ".forgejo/workflows/ci.yaml",
      "state": "disabled_manually",
      "created_at": "2026-10-09T08:00:00Z",
      "updated_at": "2026-10-09T08:00:00Z",
      "url": "https://frem.sh/api/v1/repos/<owner>/<repo>/actions/workflows/ci.yaml",
      "html_url": "https://frem.sh/<owner>/<repo>/src/branch/main/.forgejo/workflows/ci.yaml",
      "badge_url": "https://frem.sh/<owner>/<repo>/badges/workflows/ci.yaml/badge.svg?branch=main"
    }
  ],
  "total_count": 1
}
  • state is active of disabled_manually. Het is dezelfde instelling die de knoppen wijzigen, dus de interface en de API zijn het altijd met elkaar eens.
  • name is de name: van de workflow, of de bestandsnaam als die er geen heeft. created_at en updated_at zijn allebei het tijdstip van de laatste commit op de standaardbranch, zoals bij Gitea, niet de eigen geschiedenis van het bestand.
  • In- en uitschakelen vereist beheerdersrechten op de repository, net als de knoppen. Een gebruiker met schrijfrechten krijgt 403. Dit is strenger dan bij Gitea, waar ook schrijvers het mogen.
  • 404 voor een bestand dat geen workflow op de standaardbranch is. Een tikfout, een bestand op een andere branch, of een bestand dat geen .yml/.yaml in de workflowmap is, wordt geweigerd in plaats van vastgelegd.
  • Een gearchiveerde repository antwoordt met 423 op in- en uitschakelen. Lezen kan nog wel.
  • Beide aanroepen zijn idempotent. Een uitgeschakelde workflow uitschakelen geeft 204 en verandert niets.
  • Wat “uitgeschakeld” tegenhoudt: runs door events (push, pull request en de rest), geplande runs, en het opnieuw starten van bestaande runs (POST .../rerun antwoordt met 422). Een handmatige dispatch (POST .../actions/workflows/<workflow_id>/dispatches) draait nog steeds, precies zoals Workflow uitvoeren in de interface.
  • ffp_*-tokens kunnen deze routes niet aanroepen. Ze vereisen een Forgejo-PAT (scope write:repository voor in- en uitschakelen) of een sessie, net als annuleren en opnieuw starten.

Workflowlogs programmatisch ophalen

De webinterface van Forgejo toont de logs van action-runs interactief. Voor programmatische toegang (meldingen bij fouten, debugscripts, exports voor compliance, AI-agents die fouten beoordelen) zijn er twee endpoints, afhankelijk van het type token dat je hebt:

Met een Forgejo-PAT of sessiecookie

curl -H "Authorization: token <forgejo-pat>" \
  https://frem.sh/api/v1/repos/<owner>/<repo>/actions/runs/<run_id>/logs

Geeft text/plain terug: alle jobs van de run achter elkaar, met de koppen === job: <name> (status=<status>, attempt=<n>) === tussen de jobs. De <run_id> is de globale id die Forgejo teruggeeft uit GET /api/v1/repos/<owner>/<repo>/actions/runs (dezelfde id die de webinterface toont in /<owner>/<repo>/actions/runs/<n>). De toegangscontrole is de standaard leescontrole van Forgejo op de repository; botgebruikers met het juiste lidmaatschap van de organisatie werken hetzelfde als menselijke gebruikers.

Met een PAT voor de fremforge-API (ffp_*)

Begint je token met ffp_, inclusief PAT’s die in de beheeromgeving zijn aangemaakt, tokens die je ontvangt van POST /_app/api/v1/auth/token-exchange (OIDC-uitwisseling) en tokens die worden uitgegeven door POST /_app/api/v1/oauth/token (client_credentials), dan herkent Forgejo het niet. Gebruik dan de proxy van de fremforge-API:

curl -H "Authorization: Bearer <ffp_…>" \
  https://frem.sh/_app/api/v1/orgs/<org>/repos/<repo>/actions/runs/<run_id>/logs

Dezelfde vorm van het antwoord (text/plain, jobs achter elkaar, koppen ertussen). Vereiste scope: runners:read. De proxy controleert de binding van het token aan de organisatie (<org> in de URL moet overeenkomen met de organisatie van het token) voordat het verzoek met een systeemcredential naar Forgejo wordt doorgestuurd. Die systeemcredential verlaat het platform nooit, dus een uitgelekte PAT van een klant kan alleen de logs van de eigen organisatie lezen.

Beide endpoints geven dezelfde body terug, dus een aanroeper die van authenticatievorm wisselt, hoeft alleen de URL en de Authorization-header aan te passen.

Opmerking over de tijdelijke oplossing. De proxy /api/v1/orgs/<org>/repos/<repo>/... is een tijdelijke brug totdat Forgejo upstream API-domeintokens (ffp_*) ondersteunt op zijn eigen endpoint /api/v1/repos/<owner>/<repo>/.... Zodra dat er is, wordt de proxy uitgefaseerd en gebruiken ffp_*-tokens hetzelfde pad als Forgejo-PAT’s. De vorm van het antwoord blijft gelijk; alleen de vorm van de URL verandert.

Wanneer logs niet beschikbaar zijn

  • 404: run niet gevonden, of niet van de repository in de URL.
  • 410: de logs zijn verwijderd door de opschoontaak (action-runs ouder dan de bewaartermijn).
  • 502: de Forgejo-origin is onbereikbaar. Probeer het opnieuw; blijft het zo, kijk dan op status.frem.sh.

Zie ook