Skip to content

Merge pull request #27 from ix-infrastructure/feat/skip-pro-feature-msgs #32

Merge pull request #27 from ix-infrastructure/feat/skip-pro-feature-msgs

Merge pull request #27 from ix-infrastructure/feat/skip-pro-feature-msgs #32

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
# Cancel superseded runs on the same ref so rapid pushes don't pile up runners.
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
validate:
name: Validate plugin structure
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- name: Validate JSON files
run: |
echo "── JSON validation ──"
for f in .claude-plugin/plugin.json .claude-plugin/marketplace.json hooks/hooks.json; do
if jq -e . "$f" >/dev/null 2>&1; then
echo " [ok] $f"
else
echo " [FAIL] $f is invalid JSON"
exit 1
fi
done
# Belt-and-suspenders: parse every committed JSON file (manifests +
# fixtures), not just the three core manifests above. node is preinstalled
# on ubuntu-latest; node_modules/.git are excluded.
- name: Validate all JSON parses
run: |
set -euo pipefail
fail=0
while IFS= read -r -d '' f; do
if node -e "JSON.parse(require('fs').readFileSync(process.argv[1],'utf8'))" "$f"; then
echo " [ok] $f"
else
echo " [FAIL] invalid JSON: $f"
fail=1
fi
done < <(find . -name '*.json' \
-not -path './.git/*' -not -path '*/node_modules/*' -not -path '*/dist/*' -print0)
exit $fail
- name: Validate plugin version consistency
run: |
echo "── Version consistency ──"
PLUGIN_VER=$(jq -r '.version' .claude-plugin/plugin.json)
MARKETPLACE_VER=$(jq -r '.plugins[0].version' .claude-plugin/marketplace.json)
echo " plugin.json: $PLUGIN_VER"
echo " marketplace.json: $MARKETPLACE_VER"
if [ "$PLUGIN_VER" != "$MARKETPLACE_VER" ]; then
echo " [FAIL] version mismatch"
exit 1
fi
echo " [ok] versions match"
- name: Validate expected skills
run: |
echo "── Skills ──"
FAIL=0
for skill in ix-understand ix-investigate ix-impact ix-plan ix-debug ix-architecture ix-docs; do
if [ -f "skills/$skill/SKILL.md" ]; then
echo " [ok] $skill"
else
echo " [FAIL] missing: skills/$skill/SKILL.md"
FAIL=1
fi
done
exit $FAIL
- name: Validate expected agents
run: |
echo "── Agents ──"
FAIL=0
for agent in ix-explorer ix-system-explorer ix-bug-investigator ix-safe-refactor-planner ix-architecture-auditor; do
if [ -f "agents/$agent.md" ]; then
echo " [ok] $agent"
else
echo " [FAIL] missing: agents/$agent.md"
FAIL=1
fi
done
exit $FAIL
- name: Validate hooks
run: |
echo "── Hooks ──"
FAIL=0
for hook in ix-briefing.sh ix-intercept.sh ix-read.sh ix-bash.sh ix-pre-edit.sh ix-ingest.sh ix-map.sh; do
if [ -f "hooks/$hook" ] && [ -x "hooks/$hook" ]; then
echo " [ok] $hook"
elif [ -f "hooks/$hook" ]; then
echo " [FAIL] $hook exists but is not executable"
FAIL=1
else
echo " [FAIL] missing: hooks/$hook"
FAIL=1
fi
done
exit $FAIL
shellcheck:
name: Shellcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
# shellcheck is preinstalled on ubuntu-latest. Scope to error severity so
# the gate catches real bugs without failing on stylistic notes. Covers
# every committed *.sh (hooks, libs, installers, tests), not just hooks/.
- name: Run shellcheck on all shell scripts
run: |
set -euo pipefail
shellcheck --version
mapfile -d '' files < <(find . -name '*.sh' \
-not -path './.git/*' -not -path '*/node_modules/*' -print0)
if [ ${#files[@]} -eq 0 ]; then
echo "no shell scripts found"; exit 0
fi
printf 'checking: %s\n' "${files[@]}"
shellcheck --severity=error "${files[@]}"
# ── Aggregate gate ───────────────────────────────────────────────────────
# One stable required-status-check context. Fails if any upstream job failed
# OR was skipped/cancelled, so the job graph can be reshaped without orphaning
# the required check.
ci-success:
name: CI Passed
if: always()
needs: [validate, shellcheck]
runs-on: ubuntu-latest
steps:
- name: Verify all required jobs succeeded
run: |
echo "validate=${{ needs.validate.result }}"
echo "shellcheck=${{ needs.shellcheck.result }}"
[ "${{ needs.validate.result }}" = "success" ] \
&& [ "${{ needs.shellcheck.result }}" = "success" ]