Skip to content

ci(skill): publish OpenMAIC skill to ClawHub #12

ci(skill): publish OpenMAIC skill to ClawHub

ci(skill): publish OpenMAIC skill to ClawHub #12

name: Publish OpenMAIC skill
# Required repository setup:
# - Create a GitHub Environment named `clawhub-release`.
# - Restrict its deployment branches to `main` with a custom policy.
# - Store `CLAWHUB_TOKEN` as an Environment secret.
# - Do not also store `CLAWHUB_TOKEN` as a repository secret.
on:
pull_request:
branches: [main]
paths:
- "skills/openmaic/**"
- ".github/scripts/check-clawhub-version.mjs"
- ".github/workflows/publish-openmaic-skill.yml"
push:
branches: [main]
paths:
- "skills/openmaic/**"
- ".github/scripts/check-clawhub-version.mjs"
- ".github/workflows/publish-openmaic-skill.yml"
workflow_dispatch:
inputs:
dry_run:
description: "Preview the current main branch without publishing"
type: boolean
default: true
version:
description: "Optional version without build metadata; leave empty for automatic patch"
type: string
default: ""
jobs:
reject-invalid-dispatch:
name: Reject publish outside main
if: >-
github.event_name == 'workflow_dispatch' &&
!inputs.dry_run && github.ref != 'refs/heads/main'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Reject publish outside main
run: |
echo "::error::Publishing is only allowed from the main branch."
exit 1
preview:
name: Preview ClawHub publish
if: >-
github.event_name == 'pull_request' ||
(github.event_name == 'workflow_dispatch' && inputs.dry_run)
runs-on: ubuntu-latest
permissions:
contents: read
concurrency:
group: clawhub-preview-${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.run_id }}
cancel-in-progress: true
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
repository: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || 'main' }}
persist-credentials: false
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22
- name: Check ClawHub version script syntax
run: node --check .github/scripts/check-clawhub-version.mjs
- name: Install ClawHub CLI
working-directory: ${{ runner.temp }}
env:
NPM_CONFIG_REGISTRY: https://registry.npmjs.org
NPM_CONFIG_USERCONFIG: ${{ runner.temp }}/empty-npmrc
run: |
: > "$NPM_CONFIG_USERCONFIG"
npm install --global --ignore-scripts clawhub@0.23.3
echo "CLAWHUB_PACKAGE_JSON=$(npm root --global)/clawhub/package.json" >> "$GITHUB_ENV"
- name: Configure ClawHub registry
run: |
python3 - <<'PY'
import json
import os
from pathlib import Path
path = Path(os.environ["RUNNER_TEMP"]) / "clawhub-preview-config.json"
path.write_text(
json.dumps({"registry": "https://clawhub.ai"}, indent=2) + "\n",
encoding="utf-8",
)
path.chmod(0o600)
PY
echo "CLAWHUB_CONFIG_PATH=$RUNNER_TEMP/clawhub-preview-config.json" >> "$GITHUB_ENV"
- name: Preview OpenMAIC skill publish
env:
PUBLISH_VERSION: ${{ github.event_name == 'workflow_dispatch' && inputs.version || '' }}
SOURCE_REPO: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }}
run: |
set -euo pipefail
source_commit="$(git rev-parse HEAD)"
if ! git cat-file -e "HEAD^{tree}:skills/openmaic" 2>/dev/null; then
echo "::notice::Skipping $source_commit because skills/openmaic was deleted."
exit 0
fi
publish_args=(
skills/openmaic
--slug openmaic
--name OpenMAIC
--owner wyuc
--source-repo "$SOURCE_REPO"
--source-commit "$source_commit"
--source-path skills/openmaic
)
if [[ -n "$PUBLISH_VERSION" ]]; then
preflight_file="$RUNNER_TEMP/clawhub-version-preflight.json"
clawhub skill publish "${publish_args[@]}" --dry-run --json | tee "$preflight_file"
if ! decision="$(PREFLIGHT_FILE="$preflight_file" node .github/scripts/check-clawhub-version.mjs)"; then
exit 1
fi
IFS=$'\t' read -r action canonical_version extra <<< "$decision"
if [[ -n "${extra:-}" || -z "$action" || -z "$canonical_version" ]]; then
echo "::error::Invalid version preflight decision."
exit 1
fi
case "$action" in
noop)
echo "::notice::The requested version already has identical content."
exit 0
;;
continue)
publish_args+=(--version "$canonical_version")
;;
*)
echo "::error::Unknown version preflight action."
exit 1
;;
esac
fi
clawhub skill publish "${publish_args[@]}" --dry-run --json
publish:
name: Publish to ClawHub
if: >-
github.event_name == 'push' ||
(github.event_name == 'workflow_dispatch' &&
github.ref == 'refs/heads/main' && !inputs.dry_run)
runs-on: ubuntu-latest
environment: clawhub-release
permissions:
contents: read
concurrency:
group: publish-openmaic-skill
cancel-in-progress: false
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
ref: ${{ github.sha }}
persist-credentials: false
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22
- name: Check ClawHub version script syntax
run: node --check .github/scripts/check-clawhub-version.mjs
- name: Install ClawHub CLI
working-directory: ${{ runner.temp }}
env:
NPM_CONFIG_REGISTRY: https://registry.npmjs.org
NPM_CONFIG_USERCONFIG: ${{ runner.temp }}/empty-npmrc
run: |
: > "$NPM_CONFIG_USERCONFIG"
npm install --global --ignore-scripts clawhub@0.23.3
echo "CLAWHUB_PACKAGE_JSON=$(npm root --global)/clawhub/package.json" >> "$GITHUB_ENV"
- name: Verify ClawHub token is configured
env:
CLAWHUB_TOKEN: ${{ secrets.CLAWHUB_TOKEN }}
run: |
if [[ -z "$CLAWHUB_TOKEN" ]]; then
echo "::error::CLAWHUB_TOKEN is not configured in the clawhub-release environment."
exit 1
fi
- name: Write ClawHub config
env:
CLAWHUB_TOKEN: ${{ secrets.CLAWHUB_TOKEN }}
run: |
set -euo pipefail
python3 - <<'PY'
import json
import os
import sys
from pathlib import Path
path = Path(os.environ["RUNNER_TEMP"]) / "clawhub-config.json"
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
try:
fd = os.open(path, flags, 0o600)
except FileExistsError:
print("::error::ClawHub config already exists in RUNNER_TEMP.", file=sys.stderr)
sys.exit(1)
with os.fdopen(fd, "w", encoding="utf-8") as config:
json.dump(
{"registry": "https://clawhub.ai", "token": os.environ["CLAWHUB_TOKEN"]},
config,
indent=2,
)
config.write("\n")
PY
echo "CLAWHUB_CONFIG_PATH=$RUNNER_TEMP/clawhub-config.json" >> "$GITHUB_ENV"
- name: Verify ClawHub authentication
run: clawhub whoami
- name: Publish OpenMAIC skill
env:
PUBLISH_VERSION: ${{ github.event_name == 'workflow_dispatch' && inputs.version || '' }}
SOURCE_REPO: ${{ github.repository }}
run: |
set -euo pipefail
source_commit="$(git rev-parse HEAD)"
git fetch --no-tags origin main
if ! git rev-parse --verify --quiet "refs/remotes/origin/main^{commit}" >/dev/null; then
echo "::error::Unable to resolve the fetched origin/main commit."
exit 1
fi
if ! git cat-file -e "HEAD^{tree}:skills/openmaic" 2>/dev/null; then
echo "::notice::Skipping $source_commit because skills/openmaic was deleted."
exit 0
fi
if ! git cat-file -e "origin/main^{tree}:skills/openmaic" 2>/dev/null; then
echo "::notice::Skipping $source_commit because skills/openmaic was removed from main."
exit 0
fi
source_tree="$(git rev-parse HEAD:skills/openmaic)"
main_tree="$(git rev-parse origin/main:skills/openmaic)"
if [[ "$source_tree" != "$main_tree" ]]; then
echo "::notice::Skipping $source_commit because skills/openmaic changed on main."
exit 0
fi
publish_args=(
skills/openmaic
--slug openmaic
--name OpenMAIC
--owner wyuc
--source-repo "$SOURCE_REPO"
--source-commit "$source_commit"
--source-path skills/openmaic
)
if [[ -n "$PUBLISH_VERSION" ]]; then
preflight_file="$RUNNER_TEMP/clawhub-version-preflight.json"
clawhub skill publish "${publish_args[@]}" --dry-run --json | tee "$preflight_file"
if ! decision="$(PREFLIGHT_FILE="$preflight_file" node .github/scripts/check-clawhub-version.mjs)"; then
exit 1
fi
IFS=$'\t' read -r action canonical_version extra <<< "$decision"
if [[ -n "${extra:-}" || -z "$action" || -z "$canonical_version" ]]; then
echo "::error::Invalid version preflight decision."
exit 1
fi
case "$action" in
noop)
echo "::notice::The requested version already has identical content."
exit 0
;;
continue)
publish_args+=(--version "$canonical_version")
;;
*)
echo "::error::Unknown version preflight action."
exit 1
;;
esac
fi
clawhub skill publish "${publish_args[@]}" --json