mirror of
https://github.com/openclaw/clawhub.git
synced 2026-08-14 00:47:57 +00:00
179 lines
6.0 KiB
YAML
179 lines
6.0 KiB
YAML
name: Update skills
|
|
|
|
on:
|
|
schedule:
|
|
- cron: "17 15 * * *"
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
concurrency:
|
|
group: update-skills
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
update:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Check out repository
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Update project skills
|
|
run: |
|
|
set -euo pipefail
|
|
# The committed .agents directory keeps updates in universal project scope.
|
|
output="$(npx --yes skills@1.5.16 update --project --yes 2>&1)"
|
|
# Headless agent detection emits extra mirrors; .agents is canonical here.
|
|
rm -rf agent/skills .claude/skills
|
|
rmdir agent .claude 2>/dev/null || true
|
|
printf '%s\n' "$output"
|
|
if grep -q "Failed to update" <<<"$output"; then
|
|
echo "One or more skills failed to update." >&2
|
|
exit 1
|
|
fi
|
|
|
|
- name: Refresh changed skill provenance
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
set -euo pipefail
|
|
shopt -s nullglob
|
|
|
|
for provenance in .agents/skills/*.provenance.json; do
|
|
changed=false
|
|
while IFS= read -r skill; do
|
|
if ! git diff --quiet -- ".agents/skills/${skill}"; then
|
|
changed=true
|
|
break
|
|
fi
|
|
done < <(jq -r '.skills | keys[]' "$provenance")
|
|
|
|
if [[ "$changed" != "true" ]]; then
|
|
continue
|
|
fi
|
|
|
|
repository="$(jq -r '.repository' "$provenance")"
|
|
slug="${repository#https://github.com/}"
|
|
slug="${slug%.git}"
|
|
resolved_commit="$(gh api "repos/${slug}/commits/HEAD" --jq .sha)"
|
|
temporary="$(mktemp)"
|
|
jq --arg commit "$resolved_commit" \
|
|
'.resolvedCommit = $commit' \
|
|
"$provenance" > "$temporary"
|
|
mv "$temporary" "$provenance"
|
|
done
|
|
|
|
- name: Stage managed skill changes
|
|
id: changes
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
git add skills-lock.json
|
|
while IFS= read -r skill; do
|
|
git add ".agents/skills/${skill}"
|
|
done < <(jq -r '.skills | keys[]' skills-lock.json)
|
|
|
|
shopt -s nullglob
|
|
provenance=(.agents/skills/*.provenance.json)
|
|
if (( ${#provenance[@]} )); then
|
|
git add "${provenance[@]}"
|
|
fi
|
|
|
|
unexpected="$(
|
|
git status --porcelain=v1 --untracked-files=all \
|
|
| awk 'substr($0, 1, 2) == "??" || substr($0, 2, 1) != " "'
|
|
)"
|
|
if [[ -n "$unexpected" ]]; then
|
|
echo "Unexpected unstaged paths changed:"
|
|
echo "$unexpected"
|
|
exit 1
|
|
fi
|
|
|
|
if git diff --cached --quiet; then
|
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Commit and push update branch
|
|
if: steps.changes.outputs.changed == 'true'
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
branch="automation/update-skills"
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
git fetch origin "refs/heads/${branch}:refs/remotes/origin/${branch}" || true
|
|
git switch -C "$branch"
|
|
git commit -m "chore: update skills"
|
|
git push --force-with-lease origin "$branch"
|
|
|
|
- uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
|
|
id: app-token
|
|
continue-on-error: true
|
|
if: steps.changes.outputs.changed == 'true'
|
|
with:
|
|
app-id: "2729701"
|
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
|
owner: ${{ github.repository_owner }}
|
|
repositories: ${{ github.event.repository.name }}
|
|
permission-pull-requests: write
|
|
|
|
- uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
|
|
id: app-token-fallback
|
|
continue-on-error: true
|
|
if: steps.changes.outputs.changed == 'true' && steps.app-token.outcome == 'failure'
|
|
with:
|
|
app-id: "2971289"
|
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY_FALLBACK }}
|
|
owner: ${{ github.repository_owner }}
|
|
repositories: ${{ github.event.repository.name }}
|
|
permission-pull-requests: write
|
|
|
|
- name: Open or update pull request
|
|
if: steps.changes.outputs.changed == 'true'
|
|
env:
|
|
GH_TOKEN: ${{ steps.app-token.outputs.token || steps.app-token-fallback.outputs.token }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
if [[ -z "${GH_TOKEN:-}" ]]; then
|
|
echo "::error::Unable to create a Barnacle GitHub App token. Check the primary GH_APP_PRIVATE_KEY and fallback GH_APP_PRIVATE_KEY_FALLBACK credentials and their pull-request permissions." >&2
|
|
exit 1
|
|
fi
|
|
|
|
branch="automation/update-skills"
|
|
body="$RUNNER_TEMP/update-skills-pr.md"
|
|
{
|
|
echo "## Summary"
|
|
echo
|
|
echo "- refresh all project skills tracked by skills-lock.json"
|
|
echo "- update committed skill content, lockfile hashes, and existing provenance metadata"
|
|
echo
|
|
echo "Generated by the daily project skill updater."
|
|
} > "$body"
|
|
|
|
number="$(
|
|
gh pr list \
|
|
--head "$branch" \
|
|
--state open \
|
|
--json number \
|
|
--jq '.[0].number // empty'
|
|
)"
|
|
if [[ -n "$number" ]]; then
|
|
gh pr edit "$number" \
|
|
--title "chore: update project skills" \
|
|
--body-file "$body"
|
|
else
|
|
gh pr create \
|
|
--base main \
|
|
--head "$branch" \
|
|
--title "chore: update project skills" \
|
|
--body-file "$body"
|
|
fi
|