perf: rewrite in pure Python stdlib — no apt-get, no jq, no curl
This commit is contained in:
parent
3b65de7154
commit
be6ed16735
|
|
@ -19,134 +19,93 @@ inputs:
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
- name: Install runtime dependencies
|
- name: Register skill version
|
||||||
shell: bash
|
shell: python3 {0}
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
MISSING=""
|
|
||||||
command -v jq >/dev/null 2>&1 || MISSING="$MISSING jq"
|
|
||||||
command -v curl >/dev/null 2>&1 || MISSING="$MISSING curl"
|
|
||||||
command -v python3 >/dev/null 2>&1 || MISSING="$MISSING python3"
|
|
||||||
if [ -n "$MISSING" ]; then
|
|
||||||
apt-get update -qq
|
|
||||||
apt-get install -y -qq $MISSING ca-certificates
|
|
||||||
else
|
|
||||||
echo "All dependencies already available, skipping install"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Load skill doc
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
SKILL_SUBPATH: ${{ env.SKILL_SUBPATH }}
|
|
||||||
SKILL_DOC_PATH: ${{ env.SKILL_DOC_PATH }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
DOC_PATH="${SKILL_DOC_PATH:-SKILL.md}"
|
|
||||||
BASE="${SKILL_SUBPATH:+$SKILL_SUBPATH/}"
|
|
||||||
ABS="${BASE}${DOC_PATH}"
|
|
||||||
|
|
||||||
if [ ! -f "$ABS" ]; then
|
|
||||||
FALLBACK="${BASE}README.md"
|
|
||||||
if [ -f "$FALLBACK" ]; then
|
|
||||||
ABS="$FALLBACK"
|
|
||||||
DOC_PATH="README.md"
|
|
||||||
else
|
|
||||||
echo "ERROR: skill doc not found at $ABS"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Using doc: $ABS"
|
|
||||||
jq -Rs . < "$ABS" > /tmp/skill_doc.json
|
|
||||||
echo "RESOLVED_DOC_PATH=$DOC_PATH" >> "$GITHUB_ENV"
|
|
||||||
|
|
||||||
- name: Register version
|
|
||||||
shell: bash
|
|
||||||
env:
|
env:
|
||||||
INPUT_CLIENT_KEY: ${{ inputs.client_key }}
|
INPUT_CLIENT_KEY: ${{ inputs.client_key }}
|
||||||
INPUT_API_BASE: ${{ inputs.api_base }}
|
INPUT_API_BASE: ${{ inputs.api_base }}
|
||||||
INPUT_SKILL_SLUG: ${{ inputs.skill_slug }}
|
INPUT_SKILL_SLUG: ${{ inputs.skill_slug }}
|
||||||
INPUT_RELEASE_NOTE: ${{ inputs.release_note }}
|
INPUT_RELEASE_NOTE: ${{ inputs.release_note }}
|
||||||
SKILL_SUBPATH: ${{ env.SKILL_SUBPATH }}
|
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: |
|
run: |
|
||||||
set -euo pipefail
|
import os, json, sys
|
||||||
|
from urllib.request import urlopen, Request
|
||||||
|
from urllib.error import HTTPError
|
||||||
|
|
||||||
# Resolve slug: input → package.json → pyproject.toml → repo name
|
api_base = os.environ['INPUT_API_BASE'].rstrip('/')
|
||||||
SLUG="${INPUT_SKILL_SLUG:-}"
|
client_key = os.environ['INPUT_CLIENT_KEY']
|
||||||
BASE_DIR="${SKILL_SUBPATH:-.}"
|
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('/')
|
||||||
|
|
||||||
if [ -z "$SLUG" ] && [ -f "${BASE_DIR}/package.json" ]; then
|
base_dir = subpath if subpath else '.'
|
||||||
SLUG=$(jq -r '.name // empty' "${BASE_DIR}/package.json" | sed 's|.*/||')
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$SLUG" ] && [ -f "${BASE_DIR}/pyproject.toml" ]; then
|
# Resolve skill slug
|
||||||
SLUG=$(python3 -c "
|
if not skill_slug:
|
||||||
import sys, tomllib
|
pkg = os.path.join(base_dir, 'package.json')
|
||||||
d = tomllib.load(open(sys.argv[1],'rb'))
|
if os.path.exists(pkg):
|
||||||
print((d.get('project',{}).get('name') or d.get('tool',{}).get('poetry',{}).get('name') or ''))
|
name = json.load(open(pkg)).get('name', '')
|
||||||
" "${BASE_DIR}/pyproject.toml" 2>/dev/null || true)
|
skill_slug = name.split('/')[-1] if name else ''
|
||||||
SLUG="${SLUG##*/}"
|
if not skill_slug:
|
||||||
fi
|
skill_slug = repo.split('/')[-1]
|
||||||
|
|
||||||
if [ -z "$SLUG" ]; then
|
# Load skill doc
|
||||||
SLUG="${GITHUB_REPOSITORY##*/}"
|
doc_abs = os.path.join(subpath, doc_path) if subpath else doc_path
|
||||||
fi
|
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)
|
||||||
|
|
||||||
echo "Registering slug=$SLUG version=${GITHUB_REF_NAME}"
|
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
|
# Exchange client key for access token
|
||||||
SESSION_RES=$(curl -fsS -X POST "${INPUT_API_BASE}/auth/skill-credit/session" \
|
status, resp = post(f'{api_base}/auth/skill-credit/session', {'clientKey': client_key})
|
||||||
-H "Content-Type: application/json" \
|
token = resp.get('accessToken', '')
|
||||||
-d "{\"clientKey\":\"${INPUT_CLIENT_KEY}\"}")
|
if not token:
|
||||||
|
print(f'ERROR: failed to get access token (HTTP {status}): {resp}', flush=True)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
ACCESS_TOKEN=$(echo "$SESSION_RES" | jq -r '.accessToken // empty')
|
# Register
|
||||||
if [ -z "$ACCESS_TOKEN" ]; then
|
payload = {
|
||||||
echo "ERROR: failed to get access token"
|
'skill_slug': skill_slug,
|
||||||
echo "$SESSION_RES"
|
'version': ref_name,
|
||||||
exit 1
|
'release_note': release_note,
|
||||||
fi
|
'source_type': 'git_ci',
|
||||||
|
'repo_url': f'{server_url}/{repo}.git',
|
||||||
# Build and POST registration payload
|
'repo_subpath': subpath,
|
||||||
RUNTIME_META=$(jq -nc \
|
'git_ref': ref_name,
|
||||||
--arg entry "${SKILL_SUBPATH:+$SKILL_SUBPATH/}scripts" \
|
'commit_sha': sha,
|
||||||
'{entry_hint: $entry, provider: "forgejo"}')
|
'skill_doc_path': doc_path,
|
||||||
|
'skill_doc_content': doc_content,
|
||||||
jq -n \
|
'runtime_meta': {'entry_hint': f'{subpath + "/" if subpath else ""}scripts', 'provider': 'forgejo'},
|
||||||
--arg slug "$SLUG" \
|
}
|
||||||
--arg ver "${GITHUB_REF_NAME}" \
|
status, resp = post(f'{api_base}/ecom/skills/register-by-slug', payload, token)
|
||||||
--arg note "${INPUT_RELEASE_NOTE:-}" \
|
if not (200 <= status < 300):
|
||||||
--arg url "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" \
|
print(f'ERROR: registration failed HTTP {status}: {resp}', flush=True)
|
||||||
--arg sub "${SKILL_SUBPATH:-}" \
|
sys.exit(1)
|
||||||
--arg ref "${GITHUB_REF_NAME}" \
|
print(f'Registered successfully: {json.dumps(resp, indent=2)}', flush=True)
|
||||||
--arg sha "${GITHUB_SHA}" \
|
|
||||||
--arg doc_p "${RESOLVED_DOC_PATH:-SKILL.md}" \
|
|
||||||
--slurpfile doc_c /tmp/skill_doc.json \
|
|
||||||
--argjson meta "$RUNTIME_META" \
|
|
||||||
'{
|
|
||||||
skill_slug: $slug,
|
|
||||||
version: $ver,
|
|
||||||
release_note: $note,
|
|
||||||
source_type: "git_ci",
|
|
||||||
repo_url: $url,
|
|
||||||
repo_subpath: $sub,
|
|
||||||
git_ref: $ref,
|
|
||||||
commit_sha: $sha,
|
|
||||||
skill_doc_path: $doc_p,
|
|
||||||
skill_doc_content: $doc_c[0],
|
|
||||||
runtime_meta: $meta
|
|
||||||
}' > /tmp/payload.json
|
|
||||||
|
|
||||||
HTTP_CODE=$(curl -sS -o /tmp/register_response.json -w '%{http_code}' \
|
|
||||||
-X POST "${INPUT_API_BASE}/ecom/skills/register-by-slug" \
|
|
||||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d @/tmp/payload.json)
|
|
||||||
|
|
||||||
if [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 300 ]; then
|
|
||||||
echo "ERROR: registration failed HTTP $HTTP_CODE"
|
|
||||||
cat /tmp/register_response.json
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Registered successfully:"
|
|
||||||
cat /tmp/register_response.json
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue