Skip to content

chore(auto): sync skills/docs for 4ef135fb06ee6a8e236b2da981803cebd87… #69

chore(auto): sync skills/docs for 4ef135fb06ee6a8e236b2da981803cebd87…

chore(auto): sync skills/docs for 4ef135fb06ee6a8e236b2da981803cebd87… #69

name: Auto Sync Skills and Docs
on:
push:
branches:
- develop
permissions:
contents: read
pull-requests: read
jobs:
detect-eligible-commit:
runs-on: ubuntu-latest
outputs:
should_run: ${{ steps.detect.outputs.should_run }}
reason: ${{ steps.detect.outputs.reason }}
pr_number: ${{ steps.detect.outputs.pr_number }}
commit_sha: ${{ steps.detect.outputs.commit_sha }}
assignee: ${{ steps.detect.outputs.assignee }}
auto_pr_title: ${{ steps.detect.outputs.auto_pr_title }}
steps:
- name: Determine whether commit should be processed
id: detect
uses: actions/github-script@v8
with:
script: |
const sha = context.sha;
const actor = context.actor || '';
const headMessage = context.payload?.head_commit?.message || '';
const skip = (reason) => {
core.setOutput('should_run', 'false');
core.setOutput('reason', reason);
core.setOutput('pr_number', '');
core.setOutput('commit_sha', sha);
core.setOutput('assignee', '');
core.setOutput('auto_pr_title', '');
};
// Ignore bot/app actors
if (actor.endsWith('[bot]') || actor.toLowerCase().includes('github-app')) {
skip(`Skipped bot/app actor: ${actor}`);
return;
}
// Ignore explicit skip marker commits
if (headMessage.includes('[skip skill-doc-sync]')) {
skip('Skipped due to commit marker [skip skill-doc-sync]');
return;
}
// Fetch PRs associated with this commit
const pulls = await github.rest.repos.listPullRequestsAssociatedWithCommit({
owner: context.repo.owner,
repo: context.repo.repo,
commit_sha: sha,
});
const mergedToDevelop = (pulls.data || []).find(pr =>
pr.merged_at && pr.base?.ref === 'develop'
);
// Ignore direct commits (no merged PR associated)
if (!mergedToDevelop) {
skip('Skipped direct commit or non-PR merge commit');
return;
}
// Ignore PRs raised by automation to avoid circular updates
const automationPR =
(mergedToDevelop.labels || []).some(l => l.name === 'auto-skill-doc-sync') ||
(mergedToDevelop.title || '').startsWith('chore(auto): sync skills/docs') ||
(mergedToDevelop.head?.ref || '').startsWith('auto/skill-doc-sync/');
if (automationPR) {
skip('Skipped automation sync PR merge to avoid circular updates');
return;
}
// Ignore merged PRs authored by bot accounts
const prUser = mergedToDevelop.user?.login || '';
if (prUser.endsWith('[bot]')) {
skip(`Skipped bot-authored merged PR: #${mergedToDevelop.number}`);
return;
}
// Resolve original commit author login when available.
const commitResp = await github.rest.repos.getCommit({
owner: context.repo.owner,
repo: context.repo.repo,
ref: sha,
});
const commitAuthorLogin = commitResp.data?.author?.login || '';
const commitCommitterLogin = commitResp.data?.committer?.login || '';
let assignee = commitAuthorLogin || commitCommitterLogin || prUser;
if (assignee.endsWith('[bot]')) {
assignee = prUser;
}
// Build a meaningful docs PR title from the source PR title.
const sourceTitleRaw = (mergedToDevelop.title || '').trim();
const sourceTitle = sourceTitleRaw
.replace(/^(feat|fix|docs|chore|refactor|test|build|ci|perf|style)(\(.+?\))?:\s*/i, '')
.replace(/^\[[^\]]+\]\s*/, '')
.trim();
const meaningful = (sourceTitle || `sync updates from commit ${sha.substring(0, 12)}`).substring(0, 120);
const autoPrTitle = `docs: ${meaningful}`;
core.setOutput('should_run', 'true');
core.setOutput('reason', `Eligible merged PR #${mergedToDevelop.number}`);
core.setOutput('pr_number', String(mergedToDevelop.number));
core.setOutput('commit_sha', sha);
core.setOutput('assignee', assignee);
core.setOutput('auto_pr_title', autoPrTitle);
- name: Eligibility summary
run: |
echo "should_run=${{ steps.detect.outputs.should_run }}"
echo "reason=${{ steps.detect.outputs.reason }}"
echo "pr_number=${{ steps.detect.outputs.pr_number }}"
echo "commit_sha=${{ steps.detect.outputs.commit_sha }}"
echo "assignee=${{ steps.detect.outputs.assignee }}"
echo "auto_pr_title=${{ steps.detect.outputs.auto_pr_title }}"
sync-and-open-pr:
needs: detect-eligible-commit
if: needs.detect-eligible-commit.outputs.should_run == 'true'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Generate GitHub App Token
id: app-token
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: yaalalabs
repositories: |
agent-kernel
- name: Checkout code
uses: actions/checkout@v5
with:
token: ${{ steps.app-token.outputs.token }}
fetch-depth: 0
- name: Configure git
run: |
git config user.name "agent-kernel-ci[bot]"
git config user.email "agent-kernel-ci[bot]@users.noreply.github.com"
- name: Create working branch
id: branch
run: |
SHORT_SHA="${GITHUB_SHA:0:12}"
BRANCH="auto/skill-doc-sync/${SHORT_SHA}"
git checkout -b "$BRANCH"
echo "name=$BRANCH" >> "$GITHUB_OUTPUT"
- name: Prepare sync context
run: |
cat <<'EOF' > /tmp/auto-sync-context.md
# Auto Sync Context
## Source
- Commit SHA: ${{ needs.detect-eligible-commit.outputs.commit_sha }}
- Source PR: #${{ needs.detect-eligible-commit.outputs.pr_number }}
- Base branch: develop
## Skill Instructions
Read and follow the full skill at:
.agents/skills/ak-dev-sync-skills-and-docs-from-commit/SKILL.md
## Scope of Work
Analyze the commit delta against its first parent. Then:
1. **Developer skills** — inspect and patch `.agents/skills/*/SKILL.md`.
Add a new skill only if the commit introduces a repeatable contributor task.
Remove only if the capability is gone and a replacement is documented.
2. **User skills** — inspect and patch `ak-py/src/agentkernel/skills/*/SKILL.md`
and corresponding `evals/evals.json` files.
Scope: ak-init, ak-build, ak-add-capabilities, ak-add-integration,
ak-cloud-deploy, ak-test. Add/remove only when workflow boundaries changed.
3. **Documentation surfaces** — update all relevant surfaces for any
behavioral or capability change:
- `README.md`
- `DEVELOPER_GUIDE.md`
- `ak-py/README.md`
- `docs/docs/**` (intro, getting-started, reference, examples)
- `docs/sidebars.js`
- `ak-deployment/**/README.md`
- `examples/**/README.md`
4. **Inventory/catalog sync** — if `.agents/skills/` changes, update:
- `docs/docs/agent-skills.md`
- `docs/specs/agent-skills.md`
Skill counts and tables must match the actual directory tree exactly.
## Authoring Rules
- Ground every edit in the commit diff. Do not update files unrelated to the commit.
- Prefer patching existing skills/docs over creating new ones.
- Keep developer skill and user skill trees in sync with each other.
- Ensure code examples in docs are executable against the current codebase.
- If an example changed, update both its README and docs-site references.
- Validate all edited JSON files parse correctly.
- Verify docs/spec skill counts match actual `.agents/skills/` directories.
## Output Expected
Produce the following summary before finishing:
1. Commit-impact summary (what changed in the commit).
2. Skill-impact summary (which developer and user skills were updated/added/removed).
3. Documentation-impact summary (which docs surfaces were updated).
4. List of all edited files.
5. Validation results (JSON parse, skill counts, example references).
## Loop Prevention
Do NOT create or modify automation sync PRs/branches/commits that carry these markers:
- PR label: `auto-skill-doc-sync`
- Branch prefix: `auto/skill-doc-sync/`
- Commit message containing: `[skip skill-doc-sync]`
EOF
- name: Set up Node.js environment
uses: actions/setup-node@v5
- name: Install Copilot CLI
run: npm install -g @github/copilot
- name: Run skill sync with Copilot CLI
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_REQUEST_TOKEN }}
COMMIT_SHA: ${{ needs.detect-eligible-commit.outputs.commit_sha }}
SOURCE_PR_NUMBER: ${{ needs.detect-eligible-commit.outputs.pr_number }}
run: |
if [ -z "$COPILOT_GITHUB_TOKEN" ]; then
echo "COPILOT_REQUEST_TOKEN secret is not configured."
echo "Create a fine-grained PAT with Copilot Requests permission and store it as COPILOT_REQUEST_TOKEN."
exit 1
fi
PROMPT=$(cat <<EOF
You are updating this repository using the workflow skill instructions.
Primary instructions file:
- .agents/skills/ak-dev-sync-skills-and-docs-from-commit/SKILL.md
Context file:
- /tmp/auto-sync-context.md
Source inputs:
- Commit hash: ${COMMIT_SHA}
- Source PR number: #${SOURCE_PR_NUMBER}
- Base branch: develop
Task requirements:
- Follow the skill instructions exactly.
- Sync only what is required from the given commit into skills and docs.
- Keep docs/specs skill inventories and counts consistent.
- Do not modify unrelated files.
- Leave changes staged in the working tree for pull request creation.
EOF
)
copilot -p "$PROMPT" \
--allow-tool='shell(git:*)' \
--allow-tool=read \
--allow-tool=write \
--no-ask-user
- name: Push working branch
run: git push origin ${{ steps.branch.outputs.name }}
- name: Create Pull Request
uses: peter-evans/create-pull-request@v8
with:
token: ${{ steps.app-token.outputs.token }}
branch: ${{ steps.branch.outputs.name }}
base: develop
title: ${{ needs.detect-eligible-commit.outputs.auto_pr_title }}
commit-message: "chore(auto): sync skills/docs for ${{ needs.detect-eligible-commit.outputs.commit_sha }} [skip skill-doc-sync]"
body: |
Automated sync for commit `${{ needs.detect-eligible-commit.outputs.commit_sha }}` from merged PR #${{ needs.detect-eligible-commit.outputs.pr_number }}.
This PR updates skills and documentation based on the merged code changes. Please review the changes to ensure they accurately reflect the commit's impact.
labels: |
documentation
skill-sync
auto-skill-doc-sync
assignees: |
${{ needs.detect-eligible-commit.outputs.assignee }}
reviewers: |
${{ needs.detect-eligible-commit.outputs.assignee }}
amithad
malithaYL
lakindu-yl
draft: false