313 lines
12 KiB
YAML
313 lines
12 KiB
YAML
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.
|
|
# This workflow is path-filtered. Do not configure it as a required check for every PR;
|
|
# require it only through rules that apply to the paths below.
|
|
# PR previews execute the checked-out head scripts, so they intentionally receive no secrets,
|
|
# have read-only contents permission, and disable persisted checkout credentials.
|
|
# Deleting skills/openmaic does not unpublish or deprecate an existing ClawHub release;
|
|
# that registry lifecycle action must be performed manually in ClawHub.
|
|
|
|
on:
|
|
pull_request:
|
|
branches: [main]
|
|
paths:
|
|
- "skills/openmaic/**"
|
|
- ".github/scripts/check-clawhub-version.mjs"
|
|
- ".github/scripts/publish-openmaic-skill.sh"
|
|
- ".github/workflows/publish-openmaic-skill.yml"
|
|
push:
|
|
branches: [main]
|
|
paths:
|
|
- "skills/openmaic/**"
|
|
- ".github/scripts/check-clawhub-version.mjs"
|
|
- ".github/scripts/publish-openmaic-skill.sh"
|
|
- ".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 stable SemVer version (no prerelease/build); empty means 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
|
|
|
|
bash-3-compatibility:
|
|
name: Verify macOS Bash 3.2 publish compatibility
|
|
if: github.event_name == 'pull_request'
|
|
runs-on: macos-15
|
|
permissions:
|
|
contents: read
|
|
concurrency:
|
|
group: clawhub-bash3-${{ github.event.pull_request.number }}
|
|
cancel-in-progress: true
|
|
steps:
|
|
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Run publish paths with macOS Bash 3.2
|
|
run: |
|
|
set -euo pipefail
|
|
bash_version="$(/bin/bash -c 'printf "%s.%s" "${BASH_VERSINFO[0]}" "${BASH_VERSINFO[1]}"')"
|
|
if [[ "$bash_version" != "3.2" ]]; then
|
|
echo "::error::Expected macOS system Bash 3.2, found $bash_version."
|
|
exit 1
|
|
fi
|
|
|
|
CLAWHUB=/usr/bin/true \
|
|
PUBLISH_VERSION='' \
|
|
SOURCE_REPO='THU-MAIC/OpenMAIC' \
|
|
/bin/bash .github/scripts/publish-openmaic-skill.sh
|
|
|
|
compat_dir="$RUNNER_TEMP/clawhub-bash3"
|
|
mkdir -p "$compat_dir"
|
|
cat > "$compat_dir/clawhub" <<'BASH'
|
|
#!/bin/bash
|
|
printf '%s\t' "$@" >> "$CLAWHUB_CALLS"
|
|
printf '\n' >> "$CLAWHUB_CALLS"
|
|
if [[ " $* " != *" --version 0.4.0 "* ]]; then
|
|
printf '%s\n' '{"status":"would-publish","version":"0.4.0","latestVersion":"0.3.1","fingerprint":"bash3-fixture"}'
|
|
fi
|
|
BASH
|
|
cat > "$compat_dir/node" <<'BASH'
|
|
#!/bin/bash
|
|
printf 'continue\t0.4.0\n'
|
|
BASH
|
|
chmod 700 "$compat_dir/clawhub" "$compat_dir/node"
|
|
: > "$compat_dir/calls"
|
|
|
|
CLAWHUB="$compat_dir/clawhub" \
|
|
CLAWHUB_CALLS="$compat_dir/calls" \
|
|
PATH="$compat_dir:$PATH" \
|
|
PUBLISH_VERSION='0.4.0' \
|
|
RUNNER_TEMP="$compat_dir" \
|
|
SOURCE_REPO='THU-MAIC/OpenMAIC' \
|
|
/bin/bash .github/scripts/publish-openmaic-skill.sh
|
|
if [[ "$(wc -l < "$compat_dir/calls" | tr -d ' ')" != "2" ]] ||
|
|
! grep -q -- $'--version\t0.4.0\t' "$compat_dir/calls"; then
|
|
echo "::error::Bash 3.2 manual-version path did not reach canonical publish."
|
|
exit 1
|
|
fi
|
|
|
|
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 publish script syntax
|
|
run: |
|
|
node --check .github/scripts/check-clawhub-version.mjs
|
|
bash -n .github/scripts/publish-openmaic-skill.sh
|
|
|
|
- name: Install ClawHub CLI
|
|
working-directory: ${{ runner.temp }}
|
|
env:
|
|
NPM_CONFIG_REGISTRY: https://registry.npmjs.org
|
|
NPM_CONFIG_USERCONFIG: ${{ runner.temp }}/empty-npmrc
|
|
run: |
|
|
set -euo pipefail
|
|
: > "$NPM_CONFIG_USERCONFIG"
|
|
npm install --global --ignore-scripts clawhub@0.23.3 semver@7.8.5
|
|
global_root="$(npm root --global)"
|
|
if [[ -z "$global_root" ]]; then
|
|
echo "::error::npm returned an empty global package root."
|
|
exit 1
|
|
fi
|
|
echo "SEMVER_PACKAGE_JSON=$global_root/semver/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:
|
|
CLAWHUB: clawhub
|
|
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
|
|
bash .github/scripts/publish-openmaic-skill.sh --dry-run
|
|
|
|
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 }}
|
|
fetch-depth: 0
|
|
persist-credentials: false
|
|
|
|
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
|
with:
|
|
node-version: 22
|
|
|
|
- name: Check publish script syntax
|
|
run: |
|
|
node --check .github/scripts/check-clawhub-version.mjs
|
|
bash -n .github/scripts/publish-openmaic-skill.sh
|
|
|
|
- name: Install ClawHub CLI
|
|
working-directory: ${{ runner.temp }}
|
|
env:
|
|
NPM_CONFIG_REGISTRY: https://registry.npmjs.org
|
|
NPM_CONFIG_USERCONFIG: ${{ runner.temp }}/empty-npmrc
|
|
run: |
|
|
set -euo pipefail
|
|
: > "$NPM_CONFIG_USERCONFIG"
|
|
npm install --global --ignore-scripts clawhub@0.23.3 semver@7.8.5
|
|
global_root="$(npm root --global)"
|
|
if [[ -z "$global_root" ]]; then
|
|
echo "::error::npm returned an empty global package root."
|
|
exit 1
|
|
fi
|
|
echo "SEMVER_PACKAGE_JSON=$global_root/semver/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:
|
|
CLAWHUB: clawhub
|
|
EVENT_NAME: ${{ github.event_name }}
|
|
PUBLISH_VERSION: ${{ github.event_name == 'workflow_dispatch' && inputs.version || '' }}
|
|
SOURCE_REPO: ${{ github.repository }}
|
|
run: |
|
|
set -euo pipefail
|
|
source_commit="$(git rev-parse HEAD)"
|
|
handle_divergence() {
|
|
reason="$1"
|
|
case "$EVENT_NAME" in
|
|
workflow_dispatch)
|
|
echo "::error::Refusing manual publish because $reason."
|
|
exit 1
|
|
;;
|
|
push)
|
|
echo "::notice::Skipping $source_commit because $reason."
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "::error::Unexpected publish event: $EVENT_NAME."
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
if ! git rev-parse --verify --quiet "refs/remotes/origin/main^{commit}" >/dev/null; then
|
|
echo "::error::Unable to resolve the checked-out origin/main commit."
|
|
exit 1
|
|
fi
|
|
if ! git cat-file -e "HEAD^{tree}:skills/openmaic" 2>/dev/null; then
|
|
handle_divergence "skills/openmaic was deleted"
|
|
fi
|
|
if ! git cat-file -e "origin/main^{tree}:skills/openmaic" 2>/dev/null; then
|
|
handle_divergence "skills/openmaic was removed from main"
|
|
fi
|
|
source_tree="$(git rev-parse HEAD:skills/openmaic)"
|
|
main_tree="$(git rev-parse origin/main:skills/openmaic)"
|
|
if [[ "$source_tree" != "$main_tree" ]]; then
|
|
handle_divergence "skills/openmaic changed on main"
|
|
fi
|
|
bash .github/scripts/publish-openmaic-skill.sh
|