Files
molecule-ai-sdk/.gitea/workflows/ci.yml
T
hongming c42c877ce6
meta-ci-advisory / meta (advisory) (push) Successful in 5s
contracts-codegen-drift / codegen-drift (push) Successful in 10s
llm-registry-ssot-drift / llm-registry-ssot-drift (push) Successful in 9s
Test / skill-framework-cli (push) Successful in 15s
registry-ssot-drift / registry-ssot-drift (push) Successful in 12s
llm-registry-ssot-drift / llm-registry-ssot-conformance (push) Successful in 17s
contracts-codegen-drift / go-parity (push) Successful in 18s
contracts-codegen-drift / adapter-registry-conformance (push) Successful in 21s
contracts-codegen-drift / workspace-routes-manifest-conformance (push) Successful in 19s
contracts-codegen-drift / prompt-canonical-text-conformance (push) Successful in 20s
contracts-codegen-drift / platform-identity-gate-conformance (push) Successful in 20s
registry-ssot-drift / registry-ssot-conformance (push) Successful in 18s
contracts-codegen-drift / bindings-parity (push) Successful in 20s
contracts-codegen-drift / contract-conformance (push) Successful in 23s
contracts-codegen-drift / native-plugins-registry-conformance (push) Successful in 22s
contracts-codegen-drift / validate (push) Successful in 27s
contracts-codegen-drift / all-required (push) Successful in 2s
Test / package-smoke (push) Successful in 30s
Test / test (3.11) (push) Successful in 55s
Test / test (3.13) (push) Successful in 55s
Test / test (3.12) (push) Successful in 55s
Test / all-required (push) Successful in 1s
Merge pull request 'feat(enterskill): make skills agentskills.io-portable + add enterskill plugin template' (#153) from feat/enterskill-agentskills-portable into main
Reviewed-on: #153
2026-07-23 18:38:21 +00:00

171 lines
6.4 KiB
YAML

name: Test
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: pip install -e ".[test]"
- name: Run tests
run: python -m pytest tests/
- name: Lint
run: pip install ruff==0.15.21 && ruff check molecule_external_workspace/ molecule_plugin/
package-smoke:
name: package-smoke
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
- name: Build wheel and sdist
run: |
set -euo pipefail
python -m pip install --index-url https://pypi.org/simple build==1.3.0
python -m build
- name: Assert wheel contains every scaffold kind
run: |
set -euo pipefail
python - <<'PY'
import glob
import zipfile
[wheel] = glob.glob("dist/molecule_ai_sdk-*.whl")
with zipfile.ZipFile(wheel) as archive:
names = archive.namelist()
common = {".gitignore", ".gitea/workflows/ci.yml", "tests/test_scaffold.py"}
expected = {
"skill": common | {"plugin.yaml", "README.md", "skills/__PLUGIN_NAME__/SKILL.md", "adapters/claude_code.py", "adapters/codex.py"},
"mcp": common | {"plugin.yaml", "README.md", "server.py"},
"channel": common | {"plugin.yaml", "README.md", "bridge.py"},
"trigger": common | {"plugin.yaml", "README.md", "scheduler.py", "trigger_schedule.py", "schedules.yaml"},
"enterskill": common | {"plugin.yaml", "README.md", "skills/__PLUGIN_NAME__/SKILL.md"},
}
for kind, paths in expected.items():
prefix = f"molecule_plugin/templates/{kind}/"
missing = sorted(path for path in paths if prefix + path not in names)
if missing:
raise SystemExit(f"wheel missing {kind} scaffold files: {missing}")
print("wheel contains complete skill, mcp, and channel scaffolds")
PY
- name: Clean install with public dependencies and exercise CLI
run: |
set -euo pipefail
VENV_ROOT=$(mktemp -d)
python -m venv "$VENV_ROOT/venv"
PIP="$VENV_ROOT/venv/bin/pip"
PY="$VENV_ROOT/venv/bin/python"
CLI="$VENV_ROOT/venv/bin/molecule-plugin"
"$PIP" install --force-reinstall --no-cache-dir \
--index-url https://pypi.org/simple dist/*.whl
SMOKE=$(mktemp -d)
cd "$SMOKE"
for kind in skill mcp channel trigger enterskill; do
"$CLI" init "smoke-$kind" --kind "$kind"
"$CLI" validate plugin "smoke-$kind"
(cd "smoke-$kind" && "$PY" -m unittest discover -s tests -v)
done
"$CLI" channel-sdk check "smoke-channel"
"$CLI" channel-sdk check "smoke-trigger"
"$PY" - <<'PY'
from importlib.metadata import version
import molecule_external_workspace
import molecule_plugin
expected = version("molecule-ai-sdk")
assert molecule_plugin.__version__ == expected
assert molecule_external_workspace.__version__ == expected
print(f"clean wheel smoke OK: {expected}")
PY
skill-framework-cli:
# The enterskill CLI (tools/skill-framework/cli.mjs) is the official
# hard gate consumer skill repos run against the contracts/skill-framework
# family. Node-only by design (stdlib, no npm install): self-tests via the
# stdlib test runner, plus proof that the 2020-12 validator factored into
# tools/lib/jsonschema2020.mjs keeps the generator's gen/ output
# byte-identical (the codegen-drift workflow re-checks the same invariant
# across all generators).
name: skill-framework-cli
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '22'
- name: Self-test the enterskill CLI (stdlib node --test)
run: node --test "tools/skill-framework/*.test.mjs"
- name: "@enteros/brand — semantic token WCAG-AA contrast gate"
# Recomputes every gated pair of the brand semantic token contract
# with the exact formula of molecule-core's canvas a11y gate
# (canvas/src/app/__tests__/globals.a11y.test.ts); nonzero exit on
# any pair < 4.5:1. Stdlib node, no install (same posture as above).
run: node brand/scripts/validate-contrast.mjs
- name: Factored validator keeps skill-framework gen/ byte-identical
run: |
set -euo pipefail
node tools/gen-skill-framework.mjs
git diff --exit-code -- \
gen/ts/skill_framework_gen.ts \
gen/python/skill_framework_gen.py \
gen/go/molcontracts/skill_framework_gen.go
all-required:
name: all-required
needs: [test, package-smoke, skill-framework-cli]
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Assert every required dependency succeeded
run: |
set -euo pipefail
results='${{ toJSON(needs) }}'
echo "$results"
echo "$results" | python3 -c '
import json, sys
ns = json.load(sys.stdin)
bad = [(k, v.get("result")) for k, v in ns.items()
if v.get("result") != "success"]
if bad:
print("FAIL: jobs not green:", file=sys.stderr)
for k, r in bad:
print(f" - {k}: {r}", file=sys.stderr)
sys.exit(1)
print(f"OK: all {len(ns)} required jobs succeeded")
'