lumnik. / scénarios Tous les scénarios · English

Un ticket fermé dans Gitea reste ouvert dans le hub si on ne lit que les ouverts

Objectif Suivre les tickets ouverts d'une forge Gitea, paginée par l'en-tête Link, sans garder ouvert un ticket que le support a fermé.

Le support suit ses tickets clients dans Gitea. Son API pagine comme GitHub: la page suivante est dans l'en-tête Link. lumnik suit l'en-tête, page après page:

manifests/lab-docker-compose.yml
# The support team's forge: a real Gitea, its issues are the customer tickets.name: lumnik-gitea-deskservices:  gitea:    image: gitea/gitea:1.22.6    environment:      GITEA__security__INSTALL_LOCK: "true"      GITEA__database__DB_TYPE: sqlite3      # The address the hub reaches: Gitea builds its Link headers from it.      GITEA__server__ROOT_URL: http://host.docker.internal:${GITEA_PORT:-3030}/      GITEA__api__DEFAULT_PAGING_NUM: "30"    ports: ["127.0.0.1:${GITEA_PORT:-3030}:3000"]   # this machine only: the admin password is the lab's    tmpfs: ["/data"]
manifests/10-tickets.yaml
apiVersion: connectors.lumnik.io/v1kind: Connectormetadata:  name: scenario-desk-a  connector_type: rest-generic  scopes: [support]spec:  base_url: http://host.docker.internal:3030/api/v1  auth: { kind: bearer, token_env: SCENARIO_DESK_TOKEN }  endpoints:    - id: open-tickets      path: /repos/desk-admin/support/issues?state=open&type=issues      method: GET      pagination: { kind: link-header, response_path: $ }      target:        kind: hybrid        table: ext.scenario_desk_a        unique_key: $.number        promote:          - { name: title, path: $.title, type: text }          - { name: client, path: "$.labels[?(@.name =~ /client:.*/)].name", type: text }          - { name: blocking, path: "$.labels[?(@.name == 'bloquant')].name", type: text }          - { name: opened_at, path: $.created_at, type: timestamptz }
$ lm connector run scenario-desk-a
run scheduled: 7de8ffc5-8dd3-480b-b153-a8580b987f8e

$ lm run get 7de8ffc5-8dd3-480b-b153-a8580b987f8e
ID        CONNECTOR        ENDPOINT      STATUS     IN  OUT  SKIPPED  DEAD-LETTERS  STARTED           ENDED             EVALUATED
7de8ffc5  scenario-desk-a  open-tickets  Completed  60  60   0        0             2026-10-30 15:05  2026-10-30 15:05  yes
manifests/20-tickets-all.yaml
apiVersion: connectors.lumnik.io/v1kind: Connectormetadata:  name: scenario-desk-a  connector_type: rest-generic  scopes: [support]spec:  base_url: http://host.docker.internal:3030/api/v1  auth: { kind: bearer, token_env: SCENARIO_DESK_TOKEN }  endpoints:    - id: open-tickets      path: /repos/desk-admin/support/issues?state=all&type=issues      method: GET      pagination: { kind: link-header, response_path: $ }      incremental: { mode: watermark, param: since, watermark_path: $.updated_at }      target:        kind: hybrid        table: ext.scenario_desk_a        unique_key: $.number        promote:          - { name: title, path: $.title, type: text }          - { name: state, path: $.state, type: text }          - { name: client, path: "$.labels[?(@.name =~ /client:.*/)].name", type: text }          - { name: blocking, path: "$.labels[?(@.name == 'bloquant')].name", type: text }          - { name: opened_at, path: $.created_at, type: timestamptz }          - { name: updated_at, path: $.updated_at, type: timestamptz }
$ lm connector run scenario-desk-a
run scheduled: a03d4fd3-3af4-4edf-81b3-9c5d1f691da6

$ lm run get a03d4fd3-3af4-4edf-81b3-9c5d1f691da6
ID        CONNECTOR        ENDPOINT      STATUS     IN  OUT  SKIPPED  DEAD-LETTERS  STARTED           ENDED             EVALUATED
a03d4fd3  scenario-desk-a  open-tickets  Completed  15  15   0        0             2026-10-30 15:05  2026-10-30 15:05  yes

Limites

  • Un ticket supprimé dans Gitea n'est plus renvoyé: sa ligne reste dans le hub, avec son dernier état.
  • La marge de relecture vaut une minute plus la durée du run: un ticket changé juste avant est relu, jamais perdu.
  • Ce rejeu ne déclare pas X-Total-Count comme témoin du compte; total_header le permet depuis icreated/lumnik#1632, voir le scénario WordPress.
  • Forge Gitea de démonstration, tickets synthétiques.

Support · tickets clients

Le support ferme 12 tickets.

Le tableau de bord en compte toujours 72 ouverts.

Forge Gitea de démonstration

Le problème

Un filtre ne voit pas ce qui en sort.

  • L'import ne lit que les tickets ouverts.
  • Un ticket fermé n'est plus renvoyé.
  • Sa ligne reste ouverte.

Ce qui n'est pas modifié

Gitea reste tel quel.

  • Un jeton en lecture seule.
  • La pagination de Gitea, suivie par l'en-tête Link.

Ce qu'il a fallu écrire

path: …/issues?state=all
pagination: { kind: link-header }
incremental: { mode: watermark, param: since }

Tous les états, seulement ce qui a changé.

Un connecteur de 28 lignes.

Le rouge

Gitea: 60 ouverts. Le hub: 72.

  • Le run est vert.
  • 12 tickets fermés restent ouverts.

Le vert

Gitea: 57 ouverts. Le hub: 57.

  • Le lendemain, 15 tickets relus, pas 95.
  • L'état est une colonne: fermé se lit fermé.

La limite

Un ticket supprimé n'est pas vu.

  • Gitea ne renvoie plus un ticket supprimé.
  • La ligne reste dans le hub, avec son dernier état.

Essayer

Le scénario se rejoue en local.

Une vraie forge Gitea, chaque étape publiée avec sa sortie.

Ce scénario tourne sur lumnik Open, gratuit et open source.

Essayer lumnik Open →