Skip to content

About

Reusable workflows and checks for Computer MCP repositories: source policy, the organization check, the shared plugin runtime and plugin releases.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Shared Workflows

Reusable workflows and checks for Computer MCP repositories: source policy, the organization check, the shared plugin runtime and plugin releases.

CI License: Apache-2.0

Workflows · Pins · Organization check · Source policy · Adoption

Overview

These workflows let every Computer MCP repository run the same checks and releases without keeping its own copy. The organization's MAINTENANCE owns the rules; this repository implements them. Organization and source checks read the caller's full .github commit SHA and report that revision. Missing or unsupported declarations fail explicitly.

Quick look

A member's source policy caller, pinned to a reviewed commit of this repository and of the rules:

jobs:
  policy:
    uses: computer-mcp/github-workflows/.github/workflows/policy.yml@<workflow-sha>
    with:
      declaration-revision: <declaration-sha>

Workflows and actions

Entry point Inputs Outputs and permissions
plugin-runtime.yml None Pass/fail for bin/plugin_runtime.py; contents: read
plugin-release.yml Required ref, build, ci_artifact; publish=false, runner=ubuntu-24.04 published, release_id, tag; caller grants contents: write, actions: read; no secret inputs
actions/notify-catalog Required client-id, private-key run-url; receiver-scoped App token with actions: write
organization.yml Required declaration-revision; mode=online or offline; optional secret organization-token declaration-revision; GET-only observations; contents: read
policy.yml Required declaration-revision; path-exceptions='' declaration-revision; pass/fail; contents: read
terminal-demo.yml Required artifact, executable, runner; archive='', assets=.github/assets/terminal Pass/fail; contents: read
result.yml Required needs-json; optional-jobs='[]' Pass/fail aggregate; contents: read

Runtime adoption describes the unchanged digest contract. The release guide covers reproducible archives, isolated builds, immutable publication and recovery. Notification requests the website's existing pages.yml on master, with no catalog metadata. run-url proves request acceptance; inspect that run for catalog validation and deployment.

Executable automation lives in lowercase scripts/; imported Python modules use snake_case. tests/ and fixtures/ hold offline evidence. Operating and adoption guides live in docs/.

Pins and versions

This repository versions independently under the organization's VERSIONING. Consumers pin a reviewed full 40-hex commit SHA. Released pins carry a # vX.Y.Z comment; in-progress pins carry no version comment. A tag is not needed to test an in-progress commit. Update interfaces and copied runtime bytes through consumer pull requests after a representative consumer run.

Every reusable job executing shared scripts checks out its own repository at job.workflow_sha. These GitHub workflow identity fields refer to the reusable workflow rather than the caller. The release build job executes the caller's build on its own runner, without shared publisher code.

Replace <workflow-sha> and <declaration-sha> below with full 40-hex SHAs:

jobs:
  runtime:
    uses: computer-mcp/github-workflows/.github/workflows/plugin-runtime.yml@<workflow-sha>

A release caller grants the permission ceiling for the isolated jobs:

jobs:
  release:
    permissions:
      contents: write
      actions: read
    uses: computer-mcp/github-workflows/.github/workflows/plugin-release.yml@<workflow-sha>
    with:
      ref: ${{ inputs.ref }}
      publish: ${{ inputs.publish }}
      build: python3 scripts/build-package.py
      ci_artifact: widget-${commit}

The release guide supplies the complete dispatch trigger. Release callers must preserve running and queued publications and use no caches. Notification remains a dependent job or step after successful publication:

- name: Request catalog reconciliation
  id: catalog
  uses: computer-mcp/github-workflows/actions/notify-catalog@<workflow-sha>
  with:
    client-id: ${{ vars.CATALOG_APP_CLIENT_ID }}
    private-key: ${{ secrets.CATALOG_APP_PRIVATE_KEY }}

Organization check

The catalog uses organization.login and groups[].repositories[]. This checker validates the membership and name/about fields it consumes; the profile renderer owns the complete visual schema. Membership must equal the public, non-archived, non-fork inventory except .github. Every member needs a nonempty GitHub About exactly matching its catalog about.

Settings come from MAINTENANCE's default branch, branch requirements, GitHub settings prose and App table. Checks cover squash-only merging, branch cleanup, workflow token permissions, default-branch protection, required checks, merge queues, installed Apps, permission/event/repository scopes and allowed secret/variable names. Fork branch names remain upstream-owned. All API operations are GET requests; secret values are never read.

jobs:
  organization:
    uses: computer-mcp/github-workflows/.github/workflows/organization.yml@<workflow-sha>
    with:
      declaration-revision: <declaration-sha>

Online mode reads both documents at that revision and reports a missing profile/catalog.json before calling GitHub. Exit 0 means all observations match, 1 means drift/invalid input, and 2 means observations are unavailable. Administrative read access is needed for settings and App installation repository lists. A normal workflow token may produce unavailable observations. The optional organization-token secret accepts an already authorized credential; it does not provision credentials or authorize an additional stored secret.

scope: membership checks only the inventory and About sentences, which the workflow token can read; the .github repository's CI uses it. The default scope: full adds the declared settings and runs where administrative reads are available, such as an organization owner's local gh login.

Offline mode uses only the bundled declaration and GET-response fixture, labels its revision as fixture evidence and makes no live conformance claim.

Source policy

The implementation maps to MAINTENANCE: Branches and changes and Signing:

Declared rule Enforcement
Owner identity and SSH signing; GitHub-created commits signed by GitHub On default-branch pushes, every added commit must be GitHub-verified with reason valid, and use the declared owner identity plus an SSH signature or GitHub's web-flow committer identity
Dependabot may author changes Original authors are unrestricted; accepted committer/signature checks still apply
Conventional Commit types, optional scope and breaking marker PR titles and added commit subjects use the types parsed from the declaration
No tool/agent attribution; human co-authors allowed Attribution statements and identifiable tool/bot co-author trailers are rejected in PR titles and bodies, commit messages and added text; human co-authors and ordinary product references are retained
No maintainer-machine paths or local task-state references Added/modified paths, added text and messages are checked for concrete home-directory paths and local task-file references
PR titles, added content and added/modified paths; verified default-branch commits PR diffs use the merge base; pushes check their supplied range; removed lines are outside the added-content check

merge_group checks queued content and paths. Temporary queue commits are not accepted default-branch commits; final push checks verify the accepted commits. The checker reads Git blobs and forces text diffs for text files so consumer attributes cannot suppress scanning. Binary payloads are not decoded; their paths are checked. Attribution recognition is textual, not proof of the identity of every named co-author. Attribution phrases, robot prefixes, tool names and exact email addresses are maintained in data/attribution-tools.json; matching is case-insensitive and also recognizes identities with a [bot] suffix. All message positions use the same attribution predicate: a listed phrase or robot prefix followed by a recognized tool/bot identity. Tool names require a word boundary; subsequent versions, CLI suffixes, links and explanations do not change the result. Co-author trailers with an email are classified by that email: listed tool addresses are rejected and other addresses are allowed, regardless of the name. Without an email, the tool-name rule applies. Human credits and ordinary technical names are allowed.

Callers may set path-exceptions to a newline-separated string of repository-relative file globs (default empty). Matching is case-sensitive over the entire path using Python fnmatchcase: * matches any characters, including /; ? matches one character, and [seq]/[!seq] match character sets. Use / separators without absolute paths or ./.. components; blank lines are ignored. Matching files are exempt from home-directory path and local task-state reference checks in both their names and added text. Exceptions do not exempt attribution, PR titles or commit messages. The CLI accepts the same string with --path-exceptions.

Each caller owns its exceptions and must document their scope and rationale in its CONTRIBUTING or repository-specific MAINTENANCE exceptions, as permitted by shared MAINTENANCE. Keep globs limited to the required fixtures or third-party text; other files remain checked. For example, a caller with documented synthetic path fixtures and bundled upstream examples can add:

    with:
      declaration-revision: <declaration-sha>
      path-exceptions: |
        tests/fixtures/paths/*
        vendor/upstream/examples.md

Keep policy separate from build/test CI. Title edits rerun policy without replacing an existing validation result:

name: Source policy checks
on:
  pull_request:
    types: [opened, synchronize, reopened, edited]
  push:
    branches: [master]
  merge_group:
permissions:
  contents: read
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true
jobs:
  policy:
    uses: computer-mcp/github-workflows/.github/workflows/policy.yml@<workflow-sha>
    with:
      declaration-revision: <declaration-sha>

This repository's policy caller resolves organization default-branch rules to one SHA per run and calls the same policy. Until those rules reach the organization's default branch, this check correctly fails for missing declarations. No temporary organization revision is embedded.

Terminal demo

Re-record the caller's terminal demo against its freshly built CLI and compare only recording.json. Assets default to .github/assets/terminal; DESIGN and fonts are not required. The presentation toolchain pin lives in this workflow.

The build job uploads the named artifact in the same run. Use a .tar.gz to preserve executable permissions across artifact upload/download. When archive is set, it must match one .tar.gz, extracted into a fresh directory; executable is relative to that directory. Otherwise executable is relative to the downloaded artifact. Both accept globs, require exactly one regular file and reject absolute paths, .. components and paths escaping their directory. The executable must have execute permission. Choose a runner that can run it.

jobs:
  demo:
    needs: package
    uses: computer-mcp/github-workflows/.github/workflows/terminal-demo.yml@<workflow-sha>
    with:
      artifact: <artifact name uploaded by package>
      archive: <archive glob>
      executable: <path to the CLI>
      runner: <runner label>
  validate:
    if: always()
    needs: [package, demo]
    uses: computer-mcp/github-workflows/.github/workflows/result.yml@<workflow-sha>
    with:
      needs-json: ${{ toJSON(needs) }}

Aggregation

Use always() on the caller and reusable aggregate. Required dependencies must succeed. Jobs named in optional-jobs may be skipped; failure and cancellation always fail. Missing and malformed results fail too.

jobs:
  validate:
    if: always()
    needs: [package, runtime]
    uses: computer-mcp/github-workflows/.github/workflows/result.yml@<workflow-sha>
    with:
      needs-json: ${{ toJSON(needs) }}

Observe actual caller/callee check names before selecting required checks. This repository does not configure rulesets.

Local verification

Python 3.13+ runs runtime and release fixtures. Checkers use the standard library; YAML validation uses pinned PyYAML.

python3 -m venv .build/venv
.build/venv/bin/python -m pip install --no-cache-dir -r requirements-test.txt
.build/venv/bin/python -m unittest discover -s tests
.build/venv/bin/python scripts/check-workflows.py
python3 scripts/plugin-runtime.py check-workflow
python3 scripts/check-organization.py --mode offline \
  --declaration-root fixtures/declaration \
  --declaration-revision 1111111111111111111111111111111111111111 \
  --fixture fixtures/organization.json

The offline revision is a fixture label. For online checks, check out the selected .github commit, pass its directory and actual SHA, select --mode online and omit --fixture. Online reads use Git objects at that SHA, not uncommitted edits.

The workflow validator always checks YAML, duplicate keys, action pins and workflow boundaries. If actionlint is available it also runs that tool, filtering only the older-linter error for documented job.workflow_* fields. All other errors remain fatal. Tests cover runtime delivery, release assembly/recovery, publication fault injection, notifier transport, organization drift, source ranges and aggregation offline. Temporary environments belong in ignored .build/ and may be removed after checking.

The adoption checklist names consumer files and rollout prerequisites.

About

Reusable workflows and checks for Computer MCP repositories: source policy, the organization check, the shared plugin runtime and plugin releases.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages