From ee4cdcf2f6f8219771ad892d1503d487470e6df0 Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Sat, 8 Aug 2026 11:28:42 +0300 Subject: [PATCH] lexicons: add org.tangled CI, event, and secret APIs Signed-off-by: dawn --- lexicons/org/tangled/ci/getPipeline.json | 38 +++++ .../org/tangled/ci/getWorkflowDefinition.json | 56 ++++++++ .../tangled/ci/listWorkflowDefinitions.json | 54 +++++++ lexicons/org/tangled/ci/pipeline.json | 111 +++++++++++++++ lexicons/org/tangled/ci/queryPipelines.json | 91 ++++++++++++ .../org/tangled/ci/subscribePipelineLogs.json | 133 ++++++++++++++++++ lexicons/org/tangled/ci/trigger/manual.json | 47 +++++++ lexicons/org/tangled/ci/workflow.json | 91 ++++++++++++ lexicons/org/tangled/event/pullRequest.json | 13 ++ lexicons/org/tangled/event/push.json | 13 ++ lexicons/org/tangled/secret/addSecret.json | 51 +++++++ lexicons/org/tangled/secret/listSecrets.json | 72 ++++++++++ lexicons/org/tangled/secret/removeSecret.json | 45 ++++++ 13 files changed, 815 insertions(+) create mode 100644 lexicons/org/tangled/ci/getPipeline.json create mode 100644 lexicons/org/tangled/ci/getWorkflowDefinition.json create mode 100644 lexicons/org/tangled/ci/listWorkflowDefinitions.json create mode 100644 lexicons/org/tangled/ci/pipeline.json create mode 100644 lexicons/org/tangled/ci/queryPipelines.json create mode 100644 lexicons/org/tangled/ci/subscribePipelineLogs.json create mode 100644 lexicons/org/tangled/ci/trigger/manual.json create mode 100644 lexicons/org/tangled/ci/workflow.json create mode 100644 lexicons/org/tangled/event/pullRequest.json create mode 100644 lexicons/org/tangled/event/push.json create mode 100644 lexicons/org/tangled/secret/addSecret.json create mode 100644 lexicons/org/tangled/secret/listSecrets.json create mode 100644 lexicons/org/tangled/secret/removeSecret.json diff --git a/lexicons/org/tangled/ci/getPipeline.json b/lexicons/org/tangled/ci/getPipeline.json new file mode 100644 index 000000000..6acb9de6d --- /dev/null +++ b/lexicons/org/tangled/ci/getPipeline.json @@ -0,0 +1,38 @@ +{ + "lexicon": 1, + "id": "org.tangled.ci.getPipeline", + "defs": { + "main": { + "type": "query", + "parameters": { + "type": "params", + "required": [ + "pipeline" + ], + "properties": { + "pipeline": { + "type": "string", + "description": "Spindle-local pipeline id" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "ref", + "ref": "org.tangled.ci.pipeline" + } + }, + "errors": [ + { + "name": "PipelineNotFound", + "description": "Pipeline not found" + }, + { + "name": "InvalidRequest", + "description": "Invalid request parameters" + } + ] + } + } +} diff --git a/lexicons/org/tangled/ci/getWorkflowDefinition.json b/lexicons/org/tangled/ci/getWorkflowDefinition.json new file mode 100644 index 000000000..14f03d09a --- /dev/null +++ b/lexicons/org/tangled/ci/getWorkflowDefinition.json @@ -0,0 +1,56 @@ +{ + "lexicon": 1, + "id": "org.tangled.ci.getWorkflowDefinition", + "defs": { + "main": { + "type": "query", + "parameters": { + "type": "params", + "required": [ + "repo", + "workflow" + ], + "properties": { + "repo": { + "type": "string", + "format": "did" + }, + "workflow": { + "type": "string", + "minLength": 1, + "maxLength": 128 + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": [ + "workflow" + ], + "properties": { + "workflow": { + "type": "ref", + "ref": "org.tangled.ci.workflow" + } + } + } + }, + "errors": [ + { + "name": "InvalidRequest", + "description": "Invalid request parameters" + }, + { + "name": "RepoNotFound", + "description": "Repository not found" + }, + { + "name": "WorkflowNotFound", + "description": "Workflow not found" + } + ] + } + } +} diff --git a/lexicons/org/tangled/ci/listWorkflowDefinitions.json b/lexicons/org/tangled/ci/listWorkflowDefinitions.json new file mode 100644 index 000000000..5e06d9181 --- /dev/null +++ b/lexicons/org/tangled/ci/listWorkflowDefinitions.json @@ -0,0 +1,54 @@ +{ + "lexicon": 1, + "id": "org.tangled.ci.listWorkflowDefinitions", + "defs": { + "main": { + "type": "query", + "parameters": { + "type": "params", + "required": [ + "repo" + ], + "properties": { + "repo": { + "type": "string", + "format": "did" + }, + "ref": { + "type": "string", + "default": "HEAD", + "maxLength": 256 + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": [ + "workflows" + ], + "properties": { + "workflows": { + "type": "array", + "items": { + "type": "ref", + "ref": "org.tangled.ci.workflow" + } + } + } + } + }, + "errors": [ + { + "name": "InvalidRequest", + "description": "Invalid request parameters" + }, + { + "name": "RepoNotFound", + "description": "Repository not found" + } + ] + } + } +} diff --git a/lexicons/org/tangled/ci/pipeline.json b/lexicons/org/tangled/ci/pipeline.json new file mode 100644 index 000000000..87766c201 --- /dev/null +++ b/lexicons/org/tangled/ci/pipeline.json @@ -0,0 +1,111 @@ +{ + "lexicon": 1, + "id": "org.tangled.ci.pipeline", + "defs": { + "main": { + "type": "object", + "description": "A CI pipeline. Record-like, but owned by the spindle rather than a PDS.", + "required": [ + "id", + "repo", + "trigger", + "commit", + "workflows" + ], + "properties": { + "id": { + "type": "string", + "description": "Spindle-local pipeline id" + }, + "repo": { + "type": "string", + "format": "did", + "description": "Repository DID" + }, + "trigger": { + "type": "union", + "closed": false, + "refs": [ + "org.tangled.event.push", + "org.tangled.event.pullRequest", + "org.tangled.ci.trigger.manual" + ], + "description": "Trigger event that triggered this pipeline." + }, + "commit": { + "type": "string", + "description": "Commit Id this pipeline is running on" + }, + "sourceRepo": { + "type": "string", + "format": "did", + "description": "Repository DID that the commit was checked out from, if different from repo (e.g. a fork for a fork-based pull request)" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "workflows": { + "type": "array", + "description": "Triggered workflows", + "minLength": 1, + "maxLength": 50, + "items": { + "type": "ref", + "ref": "#workflow" + } + } + } + }, + "workflow": { + "type": "object", + "required": [ + "definition", + "id", + "status" + ], + "properties": { + "id": { + "type": "string", + "description": "Pipeline-local workflow id, usually same as name.", + "minLength": 1, + "maxLength": 128 + }, + "name": { + "type": "string", + "description": "Human-readable name of the workflow", + "maxLength": 128 + }, + "status": { + "type": "string", + "description": "Workflow status", + "enum": [ + "pending", + "scheduled", + "running", + "failed", + "timeout", + "cancelled", + "success" + ] + }, + "startedAt": { + "type": "string", + "format": "datetime" + }, + "finishedAt": { + "type": "string", + "format": "datetime" + }, + "error": { + "type": "string" + }, + "definition": { + "type": "ref", + "ref": "org.tangled.ci.workflow", + "description": "Workflow definition where this workflow run is originated from." + } + } + } + } +} diff --git a/lexicons/org/tangled/ci/queryPipelines.json b/lexicons/org/tangled/ci/queryPipelines.json new file mode 100644 index 000000000..e91956a5a --- /dev/null +++ b/lexicons/org/tangled/ci/queryPipelines.json @@ -0,0 +1,91 @@ +{ + "lexicon": 1, + "id": "org.tangled.ci.queryPipelines", + "defs": { + "main": { + "type": "query", + "description": "Query pipelines in a git repository", + "parameters": { + "type": "params", + "required": [ + "repo" + ], + "properties": { + "repo": { + "type": "string", + "format": "did", + "description": "DID of the repository" + }, + "commits": { + "type": "array", + "items": { + "type": "string", + "maxLength": 64, + "description": "commit id (SHA-1 or SHA-256)" + }, + "description": "Filter pipelines by commit ids." + }, + "triggers": { + "type": "array", + "items": { + "type": "string", + "knownValues": [ + "org.tangled.event.push", + "org.tangled.event.pullRequest", + "org.tangled.ci.trigger.manual" + ] + }, + "description": "Filter pipelines by trigger kind. When provided, pipelines matching any listed kind are returned; when omitted, every kind is returned." + }, + "limit": { + "type": "integer", + "description": "Maximum number of pipelines to return", + "minimum": 1, + "maximum": 250, + "default": 50 + }, + "cursor": { + "type": "string", + "description": "Pagination cursor" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": [ + "total", + "pipelines" + ], + "properties": { + "cursor": { + "type": "string" + }, + "total": { + "type": "integer", + "description": "Number of matching pipelines" + }, + "pipelines": { + "type": "array", + "items": { + "type": "ref", + "ref": "org.tangled.ci.pipeline" + } + } + } + } + }, + "errors": [ + { + "name": "InvalidRequest", + "description": "Invalid request parameters" + }, + { + "name": "RepoNotFound", + "description": "Repository not found" + } + ] + } + } +} diff --git a/lexicons/org/tangled/ci/subscribePipelineLogs.json b/lexicons/org/tangled/ci/subscribePipelineLogs.json new file mode 100644 index 000000000..fa80f43d9 --- /dev/null +++ b/lexicons/org/tangled/ci/subscribePipelineLogs.json @@ -0,0 +1,133 @@ +{ + "lexicon": 1, + "id": "org.tangled.ci.subscribePipelineLogs", + "defs": { + "main": { + "type": "subscription", + "description": "Pipeline logs stream", + "parameters": { + "type": "params", + "required": [ + "pipeline" + ], + "properties": { + "pipeline": { + "type": "string", + "description": "Pipeline ID" + }, + "workflows": { + "type": "array", + "items": { + "type": "string", + "description": "Workflow name" + }, + "description": "filter logs by specific workflows" + } + } + }, + "message": { + "schema": { + "type": "union", + "refs": [ + "#control", + "#data" + ] + } + }, + "errors": [ + { + "name": "PipelineNotFound", + "description": "Pipeline not found" + }, + { + "name": "WorkflowNotFound", + "description": "Workflow not found" + }, + { + "name": "InvalidRequest", + "description": "Invalid request parameters" + } + ] + }, + "control": { + "type": "object", + "required": [ + "time", + "workflow", + "step", + "content" + ], + "properties": { + "time": { + "type": "string", + "format": "datetime" + }, + "workflow": { + "type": "string", + "description": "workflow name" + }, + "step": { + "type": "integer", + "description": "Step ID" + }, + "content": { + "type": "string" + }, + "command": { + "type": "string", + "description": "Step command" + }, + "status": { + "type": "string", + "enum": [ + "start", + "end" + ], + "description": "Step status" + }, + "kind": { + "type": "string", + "enum": [ + "system", + "user" + ], + "description": "Step kind" + } + } + }, + "data": { + "type": "object", + "required": [ + "time", + "workflow", + "step", + "content", + "stream" + ], + "properties": { + "time": { + "type": "string", + "format": "datetime" + }, + "workflow": { + "type": "string", + "description": "workflow name" + }, + "step": { + "type": "integer", + "description": "Step ID" + }, + "content": { + "type": "string" + }, + "stream": { + "type": "string", + "enum": [ + "stdout", + "stderr" + ] + } + } + } + } +} diff --git a/lexicons/org/tangled/ci/trigger/manual.json b/lexicons/org/tangled/ci/trigger/manual.json new file mode 100644 index 000000000..8cf04c84f --- /dev/null +++ b/lexicons/org/tangled/ci/trigger/manual.json @@ -0,0 +1,47 @@ +{ + "lexicon": 1, + "id": "org.tangled.ci.trigger.manual", + "needsCbor": true, + "needsType": true, + "defs": { + "main": { + "type": "object", + "required": ["repo", "commit"], + "properties": { + "repo": { + "type": "string", + "format": "did" + }, + "commit": { + "type": "string", + "description": "Commit id the pipeline will run on.", + "minLength": 40, + "maxLength": 64 + }, + "ref": { + "type": "string", + "description": "Optional ref the commit was resolved from." + }, + "inputs": { + "type": "array", + "items": { + "type": "ref", + "ref": "#pair" + } + } + } + }, + "pair": { + "type": "object", + "required": ["key", "value"], + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + } + } +} diff --git a/lexicons/org/tangled/ci/workflow.json b/lexicons/org/tangled/ci/workflow.json new file mode 100644 index 000000000..75bc278a7 --- /dev/null +++ b/lexicons/org/tangled/ci/workflow.json @@ -0,0 +1,91 @@ +{ + "lexicon": 1, + "id": "org.tangled.ci.workflow", + "defs": { + "main": { + "type": "object", + "description": "A workflow definition", + "required": ["id", "source", "triggers"], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "hash": { + "type": "string", + "description": "Fingerprint of the workflow definition as resolved by the spindle." + }, + "name": { + "type": "string", + "description": "Human-readable name of the workflow", + "minLength": 1, + "maxLength": 128 + }, + "source": { + "type": "union", + "refs": ["#fileSource", "#externalSource"] + }, + "triggers": { + "type": "array", + "description": "Event types that triggers this workflow.", + "items": { + "type": "string", + "knownValues": [ + "org.tangled.event.push", + "org.tangled.event.pullRequest", + "org.tangled.ci.trigger.manual" + ] + } + } + } + }, + "fileSource": { + "type": "object", + "required": ["repo", "commit", "path"], + "properties": { + "repo": { + "type": "string", + "format": "did" + }, + "commit": { + "type": "string", + "minLength": 40, + "maxLength": 128 + }, + "path": { + "type": "string", + "minLength": 1 + }, + "lines": { + "type": "object", + "required": ["start", "end"], + "properties": { + "start": { + "type": "integer", + "minimum": 1 + }, + "end": { + "type": "integer", + "minimum": 1 + } + } + } + } + }, + "externalSource": { + "type": "object", + "required": ["link"], + "properties": { + "name": { + "type": "string", + "description": "human-readable name of external source" + }, + "link": { + "type": "string", + "format": "uri" + } + } + } + } +} diff --git a/lexicons/org/tangled/event/pullRequest.json b/lexicons/org/tangled/event/pullRequest.json new file mode 100644 index 000000000..ec5a911ca --- /dev/null +++ b/lexicons/org/tangled/event/pullRequest.json @@ -0,0 +1,13 @@ +{ + "lexicon": 1, + "id": "org.tangled.event.pullRequest", + "needsCbor": true, + "needsType": true, + "defs": { + "main": { + "type": "object", + "description": "When pull request is created or resubmitted.", + "properties": {} + } + } +} diff --git a/lexicons/org/tangled/event/push.json b/lexicons/org/tangled/event/push.json new file mode 100644 index 000000000..0e2942f7b --- /dev/null +++ b/lexicons/org/tangled/event/push.json @@ -0,0 +1,13 @@ +{ + "lexicon": 1, + "id": "org.tangled.event.push", + "needsCbor": true, + "needsType": true, + "defs": { + "main": { + "type": "object", + "description": "When a repository ref is updated.", + "properties": {} + } + } +} diff --git a/lexicons/org/tangled/secret/addSecret.json b/lexicons/org/tangled/secret/addSecret.json new file mode 100644 index 000000000..5f529427c --- /dev/null +++ b/lexicons/org/tangled/secret/addSecret.json @@ -0,0 +1,51 @@ +{ + "lexicon": 1, + "id": "org.tangled.secret.addSecret", + "defs": { + "main": { + "type": "procedure", + "description": "Add a CI secret", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": [ + "repo", + "key", + "value" + ], + "properties": { + "repo": { + "type": "string", + "format": "did" + }, + "key": { + "type": "string", + "maxLength": 50, + "minLength": 1 + }, + "value": { + "type": "string", + "maxLength": 200, + "minLength": 1 + } + } + } + }, + "errors": [ + { + "name": "InvalidRequest", + "description": "Invalid request parameters" + }, + { + "name": "RepoNotFound", + "description": "Repository not found" + }, + { + "name": "SecretAlreadyExists", + "description": "A secret with this key already exists." + } + ] + } + } +} diff --git a/lexicons/org/tangled/secret/listSecrets.json b/lexicons/org/tangled/secret/listSecrets.json new file mode 100644 index 000000000..be20b5e49 --- /dev/null +++ b/lexicons/org/tangled/secret/listSecrets.json @@ -0,0 +1,72 @@ +{ + "lexicon": 1, + "id": "org.tangled.secret.listSecrets", + "defs": { + "main": { + "type": "query", + "parameters": { + "type": "params", + "required": [ + "repo" + ], + "properties": { + "repo": { + "type": "string", + "format": "did" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": [ + "secrets" + ], + "properties": { + "secrets": { + "type": "array", + "items": { + "type": "ref", + "ref": "#secret" + } + } + } + } + }, + "errors": [ + { + "name": "InvalidRequest", + "description": "Invalid request parameters" + }, + { + "name": "RepoNotFound", + "description": "Repository not found" + } + ] + }, + "secret": { + "type": "object", + "required": [ + "key", + "createdAt", + "createdBy" + ], + "properties": { + "key": { + "type": "string", + "maxLength": 50, + "minLength": 1 + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "createdBy": { + "type": "string", + "format": "did" + } + } + } + } +} diff --git a/lexicons/org/tangled/secret/removeSecret.json b/lexicons/org/tangled/secret/removeSecret.json new file mode 100644 index 000000000..c177a515a --- /dev/null +++ b/lexicons/org/tangled/secret/removeSecret.json @@ -0,0 +1,45 @@ +{ + "lexicon": 1, + "id": "org.tangled.secret.removeSecret", + "defs": { + "main": { + "type": "procedure", + "description": "Remove a CI secret", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": [ + "repo", + "key" + ], + "properties": { + "repo": { + "type": "string", + "format": "did" + }, + "key": { + "type": "string", + "maxLength": 50, + "minLength": 1 + } + } + } + }, + "errors": [ + { + "name": "InvalidRequest", + "description": "Invalid request parameters" + }, + { + "name": "RepoNotFound", + "description": "Repository not found" + }, + { + "name": "SecretNotFound", + "description": "The requested secret does not exist." + } + ] + } + } +} -- 2.51.2