Tooling

Status: implemented

The files the repository's tooling reads, and the responses its website reads from GitHub, are schemas too:

  • the generated CI workflows, in ci/common. Closed: CI reads its own generated workflows back, so a key the schema does not name is generator drift;
  • the site's funding manifest, in website/funding. open at every level: the footer reads only the funding channels;
  • the GitHub responses the website reads: the sign-in exchange in website/github, and the open pull requests with their checks in website/prs. open at every object, because GitHub adds fields.

Examples

The demo on this page offers three schemas: a GitHub Actions workflow, the funding channels, and the open pull requests, each with a value it accepts. They are defined in sample.f.mjs, and the module page's demo lists them among all the others.

Where it is implemented

The modules linked above.

Demo

A workflow as this repository generates it. Closed: CI reads its own generated workflows back, so a key the schema does not name is generator drift.

import { gitHubActionSchema } from 'functionalscript/fjs/ci/common/module.f.mjs'
{} [on] → {}{} [concurrency] → or{} [permissions] → record{} [jobs] → record{} [pull_request] → or{} [merge_group] → or{} [push] → oror [] → {}record [] → {}or [] → {}or [] → {}or [] → {}{} [cancel-in-progress] → or{} [permissions] → or{} [if] → or{} [needs] → or{} [steps] → array{} [branches] → arrayor [] → recordor [] → arrayarray [] → {}{} [id] → or{} [if] → or{} [run] → or{} [shell] → or{} [uses] → or{} [with] → or{} [env] → or{} [working-directory] → or{} [continue-on-error] → oror [] → recordor [] → record{}nameonconcurrencypermissionsjobsstring{}orrecordrecord{}pull_requestmerge_grouppushoroption{}recordstringrecordoroption{}oroption{}oroption{}{}groupcancel-in-progressstringor{}runs-onpermissionsifneedstimeout-minutesstepsstringororornumberarray{}{}{}branchesortruestringoroptionrecordoroptionstringoroptionarrayarrayarraystringrecordstringarraystring{}idifrunshelluseswithenvworking-directorycontinue-on-errororoptionstringoroptionstringoroptionstringoroptionstringoroptionstringoroptionrecordoroptionrecordoroptionstringoroptiontruerecordstringrecordstring

TypeScript:

{readonly"concurrency"?:{readonly"cancel-in-progress":true|string,readonly"group":string},readonly"jobs":{readonly[k in string]?:{readonly"if"?:string,readonly"needs"?:readonly(string)[],readonly"permissions"?:{readonly[k in string]?:string},readonly"runs-on":string,readonly"steps":readonly({readonly"continue-on-error"?:true,readonly"env"?:{readonly[k in string]?:string},readonly"id"?:string,readonly"if"?:string,readonly"run"?:string,readonly"shell"?:string,readonly"uses"?:string,readonly"with"?:{readonly[k in string]?:string},readonly"working-directory"?:string})[],readonly"timeout-minutes":number}},readonly"name":string,readonly"on":{readonly"merge_group"?:{},readonly"pull_request"?:{},readonly"push"?:{readonly"branches":readonly(string)[]}},readonly"permissions":{readonly[k in string]?:string}}

JSON Schema:

{"type":"object","properties":{"concurrency":{"type":"object","properties":{"cancel-in-progress":{"anyOf":[{"const":true},{"type":"string"}]},"group":{"type":"string"}},"required":["cancel-in-progress","group"],"additionalProperties":{"not":{}}},"jobs":{"type":"object","additionalProperties":{"type":"object","properties":{"if":{"type":"string"},"needs":{"type":"array","items":{"type":"string"}},"permissions":{"type":"object","additionalProperties":{"type":"string"}},"runs-on":{"type":"string"},"steps":{"type":"array","items":{"type":"object","properties":{"continue-on-error":{"const":true},"env":{"type":"object","additionalProperties":{"type":"string"}},"id":{"type":"string"},"if":{"type":"string"},"run":{"type":"string"},"shell":{"type":"string"},"uses":{"type":"string"},"with":{"type":"object","additionalProperties":{"type":"string"}},"working-directory":{"type":"string"}},"additionalProperties":{"not":{}}}},"timeout-minutes":{"type":"number"}},"required":["runs-on","steps","timeout-minutes"],"additionalProperties":{"not":{}}}},"name":{"type":"string"},"on":{"type":"object","properties":{"merge_group":{"type":"object","additionalProperties":{"not":{}}},"pull_request":{"type":"object","additionalProperties":{"not":{}}},"push":{"type":"object","properties":{"branches":{"type":"array","items":{"type":"string"}}},"required":["branches"],"additionalProperties":{"not":{}}}},"additionalProperties":{"not":{}}},"permissions":{"type":"object","additionalProperties":{"type":"string"}}},"required":["jobs","name","on","permissions"],"additionalProperties":{"not":{}}}
Canonical form (toData)
export default [{},{"object":[{"props":{"concurrency":{"unit":16,"object":[{"props":{"cancel-in-progress":{"unit":8,"string":true},"group":{"string":true}},"rest":{}}]},"jobs":{"object":[{"props":{},"rest":{"object":[{"props":{"if":{"unit":16,"string":true},"needs":{"unit":16,"array":[{"prefix":[],"rest":{"string":true}}]},"permissions":{"unit":16,"object":[{"props":{},"rest":{"string":true}}]},"runs-on":{"string":true},"steps":{"array":[{"prefix":[],"rest":{"object":[{"props":{"continue-on-error":{"unit":24},"env":{"unit":16,"object":[{"props":{},"rest":{"string":true}}]},"id":{"unit":16,"string":true},"if":{"unit":16,"string":true},"run":{"unit":16,"string":true},"shell":{"unit":16,"string":true},"uses":{"unit":16,"string":true},"with":{"unit":16,"object":[{"props":{},"rest":{"string":true}}]},"working-directory":{"unit":16,"string":true}},"rest":{}}]}}]},"timeout-minutes":{"number":true}},"rest":{}}]}}]},"name":{"string":true},"on":{"object":[{"props":{"merge_group":{"unit":16,"object":[{"props":{},"rest":{}}]},"pull_request":{"unit":16,"object":[{"props":{},"rest":{}}]},"push":{"unit":16,"object":[{"props":{"branches":{"array":[{"prefix":[],"rest":{"string":true}}]}},"rest":{}}]}},"rest":{}}]},"permissions":{"object":[{"props":{},"rest":{"string":true}}]}},"rest":{}}]}];

parse · ok

export default {"name":"CI","on":{"pull_request":{}},"permissions":{"contents":"read"},"jobs":{"test":{"runs-on":"ubuntu-latest","timeout-minutes":30,"steps":[{"uses":"actions/checkout@v5"},{"run":"npm test"}]}}};

validate · ok

export default {"name":"CI","on":{"pull_request":{}},"permissions":{"contents":"read"},"jobs":{"test":{"runs-on":"ubuntu-latest","timeout-minutes":30,"steps":[{"uses":"actions/checkout@v5"},{"run":"npm test"}]}}};

Emergent Testing

Idle. Press Run to start the suite.

  • ./proof.f.mjs