shared-actions/register-skill/action.yaml

112 lines
4.5 KiB
YAML
Raw Normal View History

name: 'Register Skill'
description: 'Standardized registration of a skill version to the business system'
inputs:
client_key:
description: 'Authentication key for the business system'
required: true
api_base:
description: 'API gateway base URL'
default: 'https://api-gw-test.yuanwei-lnc.com'
skill_slug:
description: 'Override skill slug (defaults to package.json name or repo name)'
required: false
release_note:
description: 'Optional release note for this version'
required: false
default: ''
runs:
using: "composite"
steps:
- name: Register skill version
shell: python3 {0}
env:
INPUT_CLIENT_KEY: ${{ inputs.client_key }}
INPUT_API_BASE: ${{ inputs.api_base }}
INPUT_SKILL_SLUG: ${{ inputs.skill_slug }}
INPUT_RELEASE_NOTE: ${{ inputs.release_note }}
SKILL_SUBPATH: ${{ env.SKILL_SUBPATH }}
SKILL_DOC_PATH: ${{ env.SKILL_DOC_PATH }}
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_REF_NAME: ${{ github.ref_name }}
GITHUB_SHA: ${{ github.sha }}
GITHUB_SERVER_URL: ${{ github.server_url }}
run: |
import os, json, sys
from urllib.request import urlopen, Request
from urllib.error import HTTPError
api_base = os.environ['INPUT_API_BASE'].rstrip('/')
client_key = os.environ['INPUT_CLIENT_KEY']
skill_slug = os.environ.get('INPUT_SKILL_SLUG', '').strip()
release_note = os.environ.get('INPUT_RELEASE_NOTE', '')
subpath = os.environ.get('SKILL_SUBPATH', '').strip()
doc_path = os.environ.get('SKILL_DOC_PATH', '').strip() or 'SKILL.md'
repo = os.environ['GITHUB_REPOSITORY']
ref_name = os.environ['GITHUB_REF_NAME']
sha = os.environ['GITHUB_SHA']
server_url = os.environ['GITHUB_SERVER_URL'].rstrip('/')
base_dir = subpath if subpath else '.'
# Resolve skill slug
if not skill_slug:
pkg = os.path.join(base_dir, 'package.json')
if os.path.exists(pkg):
name = json.load(open(pkg)).get('name', '')
skill_slug = name.split('/')[-1] if name else ''
if not skill_slug:
skill_slug = repo.split('/')[-1]
# Load skill doc
doc_abs = os.path.join(subpath, doc_path) if subpath else doc_path
if not os.path.exists(doc_abs):
fallback = os.path.join(subpath, 'README.md') if subpath else 'README.md'
if os.path.exists(fallback):
doc_abs = fallback
doc_path = 'README.md'
else:
print(f'ERROR: skill doc not found: {doc_abs}', flush=True)
sys.exit(1)
doc_content = open(doc_abs).read()
print(f'Registering slug={skill_slug} version={ref_name} doc={doc_abs}', flush=True)
def post(url, body, token=None):
headers = {'Content-Type': 'application/json'}
if token:
headers['Authorization'] = f'Bearer {token}'
req = Request(url, data=json.dumps(body).encode(), headers=headers, method='POST')
try:
with urlopen(req) as r:
return r.status, json.loads(r.read())
except HTTPError as e:
return e.code, json.loads(e.read())
# Exchange client key for access token
status, resp = post(f'{api_base}/auth/skill-credit/session', {'clientKey': client_key})
token = resp.get('accessToken', '')
if not token:
print(f'ERROR: failed to get access token (HTTP {status}): {resp}', flush=True)
sys.exit(1)
# Register
payload = {
'skill_slug': skill_slug,
'version': ref_name,
'release_note': release_note,
'source_type': 'git_ci',
'repo_url': f'{server_url}/{repo}.git',
'repo_subpath': subpath,
'git_ref': ref_name,
'commit_sha': sha,
'skill_doc_path': doc_path,
'skill_doc_content': doc_content,
'runtime_meta': {'entry_hint': f'{subpath + "/" if subpath else ""}scripts', 'provider': 'forgejo'},
}
status, resp = post(f'{api_base}/ecom/skills/register-by-slug', payload, token)
if not (200 <= status < 300):
print(f'ERROR: registration failed HTTP {status}: {resp}', flush=True)
sys.exit(1)
print(f'Registered successfully: {json.dumps(resp, indent=2)}', flush=True)