diff --git a/.gitea/workflows/sync-superpowers.yml b/.gitea/workflows/sync-superpowers.yml new file mode 100644 index 0000000..22522e6 --- /dev/null +++ b/.gitea/workflows/sync-superpowers.yml @@ -0,0 +1,184 @@ +name: Sync Superpowers Skills + +on: + workflow_dispatch: + +concurrency: + group: superpowers-sync-${{ github.repository }} + cancel-in-progress: true + +env: + WORKSPACE_DIR: "/home/workspace" + SUPERPOWERS_BRANCH: "thirdparty/skill" + SUPERPOWERS_DIR: "superpowers" + SUPERPOWERS_LIST: "codex/skills/.sources/superpowers.list" + +jobs: + sync: + name: Sync to main + runs-on: ubuntu-22.04 + + steps: + - name: Prepare repo + run: | + echo "========================================" + echo "Prepare repo to WORKSPACE_DIR" + echo "========================================" + + REPO_NAME="${{ github.event.repository.name }}" + REPO_DIR="${{ env.WORKSPACE_DIR }}/$REPO_NAME" + TOKEN="${{ secrets.WORKFLOW }}" + if [ -n "$TOKEN" ]; then + REPO_URL="https://oauth2:${TOKEN}@${GITHUB_SERVER_URL#https://}/${{ github.repository }}.git" + else + REPO_URL="${GITHUB_SERVER_URL}/${{ github.repository }}.git" + fi + + if [ -d "$REPO_DIR" ]; then + if [ -d "$REPO_DIR/.git" ]; then + cd "$REPO_DIR" + git clean -fdx + git reset --hard + git fetch --all --tags --force --prune --prune-tags + else + rm -rf "$REPO_DIR" + fi + fi + + if [ ! -d "$REPO_DIR/.git" ]; then + mkdir -p "${{ env.WORKSPACE_DIR }}" + git clone "$REPO_URL" "$REPO_DIR" + cd "$REPO_DIR" + fi + + TARGET_SHA="${{ github.sha }}" + TARGET_REF="${{ github.ref }}" + if git cat-file -e "$TARGET_SHA^{commit}" 2>/dev/null; then + git checkout -f "$TARGET_SHA" + else + if [ -n "$TARGET_REF" ]; then + git fetch origin "$TARGET_REF" + git checkout -f FETCH_HEAD + else + git checkout -f "${{ github.ref_name }}" + fi + fi + + git config --global --add safe.directory "$REPO_DIR" + echo "REPO_DIR=$REPO_DIR" >> $GITHUB_ENV + + - name: Sync superpowers skills to main + shell: bash + run: | + set -euo pipefail + + cd "$REPO_DIR" + + git config user.name "playbook-bot" + git config user.email "playbook-bot@local" + + git fetch origin "$SUPERPOWERS_BRANCH" + + tmp_dir="$(mktemp -d)" + git archive --format=tar "origin/${SUPERPOWERS_BRANCH}" "${SUPERPOWERS_DIR}/skills" | tar -xf - -C "$tmp_dir" + + tmp_skills_dir="$tmp_dir/${SUPERPOWERS_DIR}/skills" + if [ ! -d "$tmp_skills_dir" ]; then + echo "ERROR: ${SUPERPOWERS_DIR}/skills not found in ${SUPERPOWERS_BRANCH}" >&2 + exit 1 + fi + + git checkout -f main + + mkdir -p "$(dirname "$SUPERPOWERS_LIST")" + + old_list="$SUPERPOWERS_LIST" + if [ -f "$old_list" ]; then + while IFS= read -r name; do + [ -n "$name" ] || continue + rm -rf "codex/skills/$name" + done < "$old_list" + fi + + names=() + for dir in "$tmp_skills_dir"/*; do + [ -d "$dir" ] || continue + name="$(basename "$dir")" + + if [ -d "codex/skills/$name" ] && ! grep -qx "$name" "$old_list" 2>/dev/null; then + echo "ERROR: skill name conflict: $name" >&2 + exit 1 + fi + + rm -rf "codex/skills/$name" + cp -R "$dir" "codex/skills/$name" + names+=("$name") + done + + printf "%s\n" "${names[@]}" | sort > "$SUPERPOWERS_LIST" + + update_block() { + local file="$1" + local start="" + local end="" + local tmp="$(mktemp)" + + { + echo "### Third-party Skills (superpowers)" + echo "" + echo "$start" + while IFS= read -r name; do + [ -n "$name" ] || continue + echo "- $name" + done < "$SUPERPOWERS_LIST" + echo "$end" + } > "$tmp" + + if grep -q "$start" "$file"; then + awk -v start="$start" -v end="$end" -v block="$tmp" ' + BEGIN { + while ((getline line < block) > 0) { buf[++n] = line } + close(block) + inblock=0 + replaced=0 + } + { + if (!replaced && $0 == start) { + for (i=1; i<=n; i++) print buf[i] + inblock=1 + replaced=1 + next + } + if (inblock) { + if ($0 == end) { inblock=0 } + next + } + print + } + ' "$file" > "${file}.tmp" + mv "${file}.tmp" "$file" + else + echo "" >> "$file" + cat "$tmp" >> "$file" + fi + + rm -f "$tmp" + } + + update_block "SKILLS.md" + + git add codex/skills SKILLS.md + + if git diff --cached --quiet; then + echo "No changes to sync." + exit 0 + fi + + git commit -m ":package: deps(skills): sync superpowers" + + TOKEN="${{ secrets.WORKFLOW }}" + if [ -n "$TOKEN" ]; then + git remote set-url origin "https://oauth2:${TOKEN}@${GITHUB_SERVER_URL#https://}/${{ github.repository }}.git" + fi + + git push origin main