Skip to content

ci: add daily upstream sync + custom skills lint#9

Open
royosherove wants to merge 1 commit into
mainfrom
chore/add-sync-workflow
Open

ci: add daily upstream sync + custom skills lint#9
royosherove wants to merge 1 commit into
mainfrom
chore/add-sync-workflow

Conversation

@royosherove
Copy link
Copy Markdown
Member

Summary

Automated daily sync from upstream Kiro Powers + CI validation for custom skills consistency.

Changes

Sync Workflow (sync-upstream.yml)

  • Schedule: Daily at 08:00 UTC (11:00 Israel time)
  • Action: Clone upstream → copy new/updated skills → create PR if changes
  • Custom skills preserved: 8 skills (module-organizer, refactoring, unit-testing, claude-agent-sdk, cross-agent-test, lambda-durable, mcporter, playwright-cli)
  • Safety: Clones from main (no release tags), filters SKILL.md only, SHA-pinned actions
  • Notifications: Creates PR (manual review before merge)

Lint Workflow (lint.yml)

  • Trigger: Every push/PR to any branch
  • Check: CUSTOM_SKILLS array (workflow) ↔ README table (sync requirement)
  • Failure: Blocks merge if lists drift
  • Speed: ~5-10s validation

Documentation (README.md)

  • Expanded custom skills table (8 items with descriptions)
  • Added sentinel comments for markdown anchoring
  • Updated sync instructions with automation details
  • Clarified prerequisites (GitHub Actions approval setting)

Security

  • ✅ All actions pinned to commit SHA + version comment
  • ✅ Grep patterns anchored to prevent false matches
  • ✅ Markdown sentinels for robust extraction

Testing

  • 10 review cycles (supply-chain hardening, edge case handling, consistency validation)
  • All checks passed (lint + architect review)

Ready to merge!

- GitHub Actions workflow: sync upstream Kiro Powers daily at 08:00 UTC
  - Clones from main branch (upstream has no release tags)
  - Preserves 8 custom skills (module-organizer, refactoring, unit-testing, etc)
  - Creates PR for manual review before merge
  - Updates README Last synced date automatically
  - Both actions pinned to SHA for supply-chain safety

- Lint workflow: verify custom skills list consistency
  - Checks CUSTOM_SKILLS array vs README table
  - Prevents drift via CI gate on all pushes/PRs
  - Runs on every commit (fast validation)

- README: updated sync instructions + custom skills documentation
  - Added sentinel comments for markdown anchoring
  - Linked to CI automation details
  - Clarified prerequisites (GitHub Actions approval setting)

Fixes: supply-chain hardening (SHA pinning), markdown robustness (sentinels),
lint validation (consistency checks), grep anchoring (no false positives)
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 17, 2026

Claude finished @royosherove's task in 1m 24s —— View job


PR Review

  • Read repo context
  • Review sync-upstream.yml
  • Review lint.yml
  • Review README.md changes
  • Post final review

Overall this is well-structured and clearly thought through. A few issues worth addressing before merge.


sync-upstream.yml

Bug — labels will be treated as a single string (line 130)

labels: 'chore, automated'

peter-evans/create-pull-request accepts labels as newline-separated values. This will create one label named "chore, automated" rather than two labels. Fix:

labels: |
  chore
  automated

Fix this →


Supply chain risk — upstream cloned unpinned from main (line 33)

git clone --depth 1 https://github.com/kirodotdev/powers.git /tmp/powers

This is acknowledged in the PR description ("no release tags"). It means a compromised upstream main branch would directly sync malicious content into a PR here. Since you cannot pin to a commit SHA on an external repo you don't control, the mitigation is the manual PR review step — which is already in place. Worth calling out explicitly in the workflow comments so future maintainers don't remove the PR creation step thinking it's just overhead.


$skill_name used in rm -rf without validation (lines 56–67)

skill_name=$(basename "$skill_dir")
...
rm -rf "$skill_name"

basename protects against .. traversal, but a skill named -rf or containing special characters could still cause unexpected behavior. A simple guard would help:

# Validate: skill name must be alphanumeric + hyphens only
if [[ ! "$skill_name" =~ ^[a-zA-Z0-9_-]+$ ]]; then
  echo "⚠️  Skipping invalid skill name: $skill_name"
  continue
fi

Fix this →


lint.yml

Fragility — single-line array assumption (line 19)

WORKFLOW_SKILLS=$(grep "^[[:space:]]*CUSTOM_SKILLS=(" .github/workflows/sync-upstream.yml \
  | sed 's/.*CUSTOM_SKILLS=(\([^)]*\)).*/\1/' \
  | tr ' ' '\n' | sed 's/"//g' | sort)

This only works when CUSTOM_SKILLS=(...) is declared on a single line. If someone reformats the array to multi-line (e.g., for readability when more skills are added), $WORKFLOW_SKILLS becomes empty and the check silently passes a false positive or fails. Consider a comment warning about this constraint:

# NOTE: CUSTOM_SKILLS must remain on a single line in sync-upstream.yml
# Multi-line format will break this extraction.

Or switch to a more robust extraction approach.

Fix this →


Missing permissions block

The lint job performs only reads, but has no explicit permissions declaration. Best practice for least-privilege:

jobs:
  verify-custom-skills-sync:
    runs-on: ubuntu-latest
    permissions:
      contents: read

README.md

Changes look clean. The sentinel comments are well-placed and the note inside the sentinel block won't be incorrectly parsed by the lint grep (which anchors to | \...``).


Summary

Severity Issue File
Bug labels creates single label instead of two sync-upstream.yml:130
Medium No $skill_name validation before rm -rf sync-upstream.yml:67
Low Lint breaks if CUSTOM_SKILLS is reformatted to multi-line lint.yml:19
Low Missing permissions: contents: read lint.yml
Info Upstream clone is unpinned (acknowledged, PR review mitigates) sync-upstream.yml:33

The labels bug is the only one that will silently misbehave at runtime. The rest are defensive hardening. Good work overall — the structure, SHA-pinning, and concurrency handling are solid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant