Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,46 @@ env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'

jobs:
versions:
name: Version declarations agree
# The README badge sat at 1.4.0 while this skill shipped 1.5.0, 1.6.0 and
# 1.6.1 (wordpress-api-pro's at 3.8.2 through 3.9.5): nothing compared
# them. Every place that states the version has to say the same thing,
# on pull requests too, so the bump that forgets one is caught before merge.
runs-on: ubuntu-latest
env:
SKILL: wordpress-api-pro/SKILL.md
steps:
- uses: actions/checkout@v4
- name: SKILL.md, README badge, package.json and "Current version" lines agree
run: |
set -euo pipefail
skill_v=$(grep -m1 '^version:' "$SKILL" | sed 's/^version:[[:space:]]*//' | tr -d '"' | tr -d "'" | xargs)
[ -n "$skill_v" ] || { echo "::error::no version: in $SKILL"; exit 1; }
mismatch=0
# Color-agnostic, and the WHOLE semver: after the x.y.z core take
# every character a prerelease or build-metadata suffix can carry -
# shields.io writes a dash inside the value as "--" and a "+" as
# itself (measured: version-1.2.0--rc.1-blue renders "1.2.0-rc.1",
# version-1.2.0+build.7-blue "1.2.0+build.7", and
# version-1.2.0+build--2-blue "1.2.0+build-2") - and stop at the first
# single dash, which is the colour separator. Then fold "--" back. A
# prerelease is a legitimate version here - release-drift.yml accepts
# one - and the check must not reject a consistent bump to it.
badge_v=$(grep -oE 'badge/version-[0-9]+\.[0-9]+\.[0-9]+(--|[0-9A-Za-z.+])*' README.md | head -1 | sed 's|badge/version-||; s|--|-|g' || true)
[ "$badge_v" = "$skill_v" ] || { echo "::error::README badge says ${badge_v:-<none>}, $SKILL says $skill_v"; mismatch=1; }
pkg_v=""
if [ -f package.json ]; then
pkg_v=$(jq -r .version package.json)
[ "$pkg_v" = "$skill_v" ] || { echo "::error::package.json says $pkg_v, $SKILL says $skill_v"; mismatch=1; }
fi
# Every "Current version: **x.y.z**" line in the README, if any.
for v in $(grep -oE 'Current version: \*\*[0-9]+\.[0-9]+\.[0-9]+[0-9A-Za-z.+-]*\*\*' README.md | grep -oE '[0-9]+\.[0-9]+\.[0-9]+[0-9A-Za-z.+-]*' || true); do
[ "$v" = "$skill_v" ] || { echo "::error::README 'Current version' says $v, $SKILL says $skill_v"; mismatch=1; }
done
[ "$mismatch" = 0 ] || { echo "::error::bump every declaration in the same commit"; exit 1; }
echo "SKILL.md, README badge${pkg_v:+, package.json} agree on $skill_v"

test:
name: Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
Expand Down
60 changes: 46 additions & 14 deletions .github/workflows/release-drift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,20 +94,52 @@ jobs:
# Collapsing both into "missing" would report "cut the release" after
# a transient API blip, sending someone to create a release that
# already exists.
ERR=$(mktemp)
set +e
DRAFT=$(gh api "repos/$GITHUB_REPOSITORY/releases/tags/v$VERSION" \
--jq '.draft' 2>"$ERR")
RC=$?
set -e
if [ "$RC" -eq 0 ]; then
STATE=$DRAFT
elif grep -qiE '404|not found' "$ERR"; then
STATE=missing
else
echo "::error::Could not query releases - this is a lookup failure, not a missing release:"
cat "$ERR" >&2
exit 1
lookup() {
ERR=$(mktemp)
set +e
DRAFT=$(gh api "repos/$GITHUB_REPOSITORY/releases/tags/v$VERSION" \
--jq '.draft' 2>"$ERR")
RC=$?
set -e
if [ "$RC" -eq 0 ]; then
STATE=$DRAFT
elif grep -qiE '404|not found' "$ERR"; then
STATE=missing
else
echo "::error::Could not query releases - this is a lookup failure, not a missing release:"
cat "$ERR" >&2
exit 1
fi
}
lookup
# On a push to main the release is cut AFTER the merge - seconds later
# when the release flow is scripted, longer by hand - and this run
# starts the moment the push lands. Failing on the first lookup turned
# every ordinary release into a red check on main's head that no later
# run could replace (measured: hostinger-mcp v1.2.1 was cut 19 s after
# the merge and the push run had already failed; wordpress-api-pro
# v3.9.5, 52 min after). So on push, wait for the release: up to
# 20 x 30 s. A bump still unreleased after ten minutes is the drift
# this check exists for and fails exactly as before. Schedule and
# dispatch runs do not wait - nothing is in flight for them.
if [ "$GITHUB_EVENT_NAME" = "push" ]; then
for attempt in $(seq 1 20); do
# Wait through a DRAFT as well as a miss: a release flow that
# creates the release as a draft and publishes it only after its
# ClawHub publish succeeded (cloudways-mcp's release.yml) shows a
# draft for the whole publish, and a draft cut by hand before the
# merge is published moments after it. Both are the interval this
# wait is for. A draft still standing after the window fails
# below, as before.
case "$STATE" in
missing) what="no v$VERSION release yet" ;;
true) what="v$VERSION is still a draft" ;;
*) break ;;
esac
echo "$what (attempt $attempt/20) - waiting 30 s for the release flow"
sleep 30
lookup
done
fi
case "$STATE" in
false)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
![OpenClaw Skill](https://img.shields.io/badge/OpenClaw-Skill-purple)
![WordPress](https://img.shields.io/badge/WordPress-REST_API-21759b)
![License: MIT--0](https://img.shields.io/badge/License-MIT--0-green)
![Version](https://img.shields.io/badge/version-3.8.2-blue)
![Version](https://img.shields.io/badge/version-3.9.5-blue)

A production-grade **Claude Code & OpenClaw skill** for managing WordPress content via the REST API — posts, pages, media, WooCommerce, Elementor, SEO meta, ACF, JetEngine — with explicit safety boundaries for agentic use.

Expand Down
Loading