feat(openmaic-skill): add secondary-development (二开) flow #28
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |