project-sync-issues
Issue/PR の状態とプロジェクト Status の自動同期を設定する。モード A は `Fandhe-AI/actions/project-sync` Composite Action を使う `.github/workflows/project-sync.yml` を生成 (PAT または GitHub App トークン)。モード B は既存の不整合を一括補正。「自動同期セットアップ」「PR レビュー時に In Review 化」「ボードと Issue の状態を同期」などで使用。
How do I install this agent skill?
npx skills add https://github.com/fandhe-ai/agent-cli-skills --skill project-sync-issuesIs this agent skill safe to install?
- Gen Agent Trust Hubpass
The skill automates GitHub Project synchronization and follows security best practices like SHA pinning for third-party actions and minimal permission scoping. It has a low-risk surface for indirect prompt injection as it processes data from external issues and pull requests.
- Socketpass
No alerts
- Snykwarn
Risk: MEDIUM · 1 issue
What does this agent skill do?
project-sync-issues
GitHub Actions ワークフローファイルを生成し、Issue/PR の状態変更をプロジェクトの Status フィールドに自動同期します。手動での一括補正モードも提供します。
前提条件
- 対象の GitHub Project がリポジトリにリンクされていること
ghCLI がインストールされ、認証済みであること(projectスコープ付き)
フロー
ユーザーに実行モードを確認する:
- 自動同期セットアップ — GitHub Actions ワークフローを生成(初回推奨)
- 手動一括補正 — 現在の不整合を一括修正(スポット実行用)
モード A: 自動同期セットアップ
Step A-1: プロジェクト情報を取得する
# オーナーを取得
gh repo view --json owner -q '.owner.login'
# プロジェクト番号を確認
gh project list --owner <owner> --format json
ユーザーに対象プロジェクトの番号を確認する。
Step A-2: 認証シークレットを案内する
GitHub Actions から Projects API にアクセスするには GITHUB_TOKEN では不足するため、以下のいずれかが必要:
方法 1: Personal Access Token(個人/小規模向け)
- GitHub Settings → Developer settings → Personal access tokens → Fine-grained tokens
- 必要なスコープ:
project(読み書き)+issues(読み書き)+pull_requests(読み書き) - リポジトリの Settings → Secrets and variables → Actions →
PROJECT_TOKENとして登録
方法 2: GitHub App トークン(Organization 向け・推奨)
- GitHub App を作成し、Organization に
Projects: Read and write権限を付与 - ワークフロー内で
actions/create-github-app-tokenを使用してトークンを生成
Step A-3: GitHub Actions ワークフローを生成する
Fandhe-AI/actions/project-sync Composite Action を使用する。.github/workflows/project-sync.yml を生成する。
参照方式(内製 action は @latest、サードパーティ action は固定 SHA):
Fandhe-AI/actions/*(本スキルでは project-sync)は組織内で管理・レビューされる内製 action のため @latest タグ参照とする(オーナー決定)。一方、サードパーティ action(actions/create-github-app-token 等)は @main / @vN 等の可動参照ではなく、検証済みのコミット SHA で固定する。生成のたびに最新 SHA を動的取得して埋め込む方式は、取得時点で上流が侵害・意図せず改変されていた場合にそのコードをそのまま導入先へ伝播させてしまう。そのためワークフロー生成時は以下のレビュー済み固定 SHA を定数として使用し、動的な最新 SHA 取得は行わない:
| Action | 固定 SHA | 対応バージョン |
|---|---|---|
actions/create-github-app-token | fee1f7d63c2ff003460e3d139729b119787bc349 | v2.2.2 |
上記 SHA は導入時点でコード内容(action.yml・参照スクリプト全文)を実際に取得・精査したうえで固定した値である。SHA を更新する必要がある場合のみ(生成のたびには実行しない)、以下の手順で変更内容そのものを精査してから本ファイルの定数とワークフロー例を更新する(対象はサードパーティ action のみ。Fandhe-AI/actions/project-sync は @latest 参照のため SHA 更新手順の対象外):
# 更新候補の最新 SHA を取得(更新作業時のみ実行。対象例: actions/create-github-app-token)
gh api repos/actions/create-github-app-token/commits/main --jq '.sha'
# 旧 SHA との差分パッチ(変更内容そのもの)を取得して精査する。ファイル名一覧だけでは不十分
gh api repos/actions/create-github-app-token/compare/<旧SHA>...<新SHA> --jq '.files[] | {filename, patch}'
# Action のエントリーポイント(action.yml)と参照される全スクリプトを新 SHA 時点の
# 内容で取得し、action が実行するコマンド・ダウンロードするバイナリ等に不審な変更が
# ないか実際に読んで確認する
gh api repos/actions/create-github-app-token/contents/action.yml?ref=<新SHA> --jq '.content' | base64 -d
差分パッチと action.yml(および参照スクリプト全文)を実際に読み、意図しない変更・不審なコマンド追加がないことを人手で確認する。可能であれば署名・リリース provenance(gh attestation verify 等)も確認する。確認が取れた場合のみ、上記の固定 SHA 表と後続のワークフロー例内 uses: 行のコメント(対応バージョン)を合わせて更新する。Fandhe-AI/actions/project-sync は @latest 参照のためこの精査手順は不要(組織内で管理・レビューされる前提でオーナーが受容済み)。
PAT を使用する場合:
name: Project Sync
on:
issues:
types: [opened, closed, reopened]
pull_request:
types: [opened, closed, ready_for_review, review_requested]
permissions:
contents: read
jobs:
sync:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Sync project status
uses: Fandhe-AI/actions/project-sync@latest
with:
project-number: '<number>'
project-owner: '<owner>'
token: ${{ secrets.PROJECT_TOKEN }}
GitHub App を使用する場合(推奨):
name: Project Sync
on:
issues:
types: [opened, closed, reopened]
pull_request:
types: [opened, closed, ready_for_review, review_requested]
permissions:
contents: read
jobs:
sync:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Generate token
id: token
uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2.2.2
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: '<owner>'
- name: Sync project status
uses: Fandhe-AI/actions/project-sync@latest
with:
project-number: '<number>'
project-owner: '<owner>'
token: ${{ steps.token.outputs.token }}
カスタム Status オプション名を使用する場合:
Status オプション名がデフォルト(Todo / In Progress / In Review / Done)と異なる場合は inputs で指定する:
- name: Sync project status
uses: Fandhe-AI/actions/project-sync@latest
with:
project-number: '<number>'
project-owner: '<owner>'
token: ${{ secrets.PROJECT_TOKEN }}
status-todo: 'バックログ'
status-in-progress: '作業中'
status-in-review: 'レビュー中'
status-done: '完了'
Step A-4: ステータスマッピングを確認する
生成するワークフローのデフォルトマッピング:
| イベント | アクション | Status |
|---|---|---|
| Issue | opened | Todo |
| Issue | closed | Done |
| Issue | reopened | Todo |
| PR | opened | In Progress |
| PR | ready_for_review | In Review |
| PR | review_requested | In Review |
| PR | closed (merged) | Done |
| PR | closed (not merged) | Todo |
ユーザーの要望に応じてマッピングをカスタマイズする。
Step A-5: ワークフローファイルを配置する
mkdir -p .github/workflows
# ワークフローファイルを .github/workflows/project-sync.yml に書き出す
ユーザーにコミット・プッシュを案内する。
モード B: 手動一括補正
プロジェクトと Issue/PR の現在の状態を比較し、不整合を一括修正する。自動同期セットアップ後の初回補正や、手動変更の反映に使用する。
Step B-1: プロジェクトアイテムを取得する
gh project item-list <number> \
--owner <owner> \
--format json \
--limit 999
Step B-2: Issue/PR の現在状態を確認する
Issue/PR タイプのアイテムに対して現在の状態を確認:
gh issue view <issue-url> --json state,labels,assignees
gh pr view <pr-url> --json state,isDraft,reviewRequests,merged
Step B-3: 状態の不一致を検出する
以下の不一致パターンを検出:
- Issue が closed だがプロジェクトの Status が Done でない → Done に更新
- Issue が open だがプロジェクトの Status が Done → Todo に更新
- PR がマージ済みだが Status が Done でない → Done に更新
- PR にレビューリクエストがあるが Status が In Review でない → In Review に更新
Step B-4: リポジトリの未追加 Issue/PR を検出する
gh issue list --state open --json number,url,title --limit 999
gh pr list --state open --json number,url,title --limit 999
プロジェクトのアイテム URL と比較して未追加分を特定する。
Step B-5: ユーザーに同期内容を確認する
検出結果を表示:
## 同期内容
### ステータス更新(N 件)
- #42: ソーシャルログイン — Status: In Progress → Done(Issue closed)
- #45: バグ修正 — Status: Done → Todo(Issue reopened)
- #50: リファクタリング PR — Status: In Progress → In Review(レビュー依頼済み)
### 新規追加(M 件)
- #55: 新機能リクエスト (Issue)
- #56: ドキュメント更新 PR
実行しますか?
Step B-6: 同期を実行する
# フィールドメタデータを取得
gh project field-list <number> --owner <owner> --format json
# ステータス更新
gh project item-edit \
--id <item-id> \
--field-id <status-field-id> \
--project-id <project-id> \
--single-select-option-id <option-id>
# 新規追加
gh project item-add <number> \
--owner <owner> \
--url <issue-or-pr-url> \
--format json
Step B-7: 同期結果を報告する
| 操作 | 件数 |
|---|---|
| ステータス更新 | N 件 |
| 新規追加 | M 件 |
| 変更なし | K 件 |
注意事項
- 認証: GitHub Actions から Projects API へのアクセスには
GITHUB_TOKENでは不足。PAT または GitHub App トークンが必要 - PAT 有効期限: fine-grained PAT は最大1年。定期ローテーション推奨
- ビルトインワークフローとの併用:
project-initでビルトインワークフロー(closed→Done, merged→Done)を有効化済みの場合、Actions ワークフローと二重に発火するが、同じ値への更新なので実害はない - PR ライフサイクル: ビルトインワークフローは closed/merged のみ対応。opened→In Progress, review_requested→In Review は Actions でのみ自動化可能
- プライベートリポジトリ: org の Settings → Actions → General でプライベートリポジトリからの Action 共有を許可する必要あり
- 手動補正モードは同期前に必ずユーザーの確認を得る
- DraftIssue タイプのアイテムは同期対象外(実 Issue が存在しないため)
- ネットワークを要する(主に API 経由。後述の「sandbox 環境での実行」節を参照)
- サードパーティ action は必ずコミット SHA で固定する:
@main/@vN等の可動参照は生成しない。上流のタグ付け替え・ブランチ改変が未検証のまま流れ込むサプライチェーンリスクを避けるため(SHA 更新時は差分を確認してから更新する)。Fandhe-AI/actions/*(内製 action)は@latest参照とする(組織内で管理・レビューされるため。オーナー決定) - permissions は最小権限で明示する: workflow レベルで
contents: readを明示する。同期処理自体はPROJECT_TOKEN/ GitHub App トークン側の権限で動作するため、GITHUB_TOKENへの追加権限は不要
検証
モード A 完了後: .github/workflows/project-sync.yml が存在し、YAML が正しく記述されていること。加えて以下を確認する:
uses:行の参照方式が正しいこと(Fandhe-AI/actions/*は@latest、それ以外(サードパーティ)は40桁の16進数コミット SHA で固定。サードパーティ側は@main・@v2.2.2・@master・任意ブランチ名等の可動参照が残っていないことを積極的に検証する):f=.github/workflows/project-sync.yml total=$(grep -c 'uses:' "$f") fandhe_total=$(grep -cE 'uses:\s*Fandhe-AI/actions/' "$f") fandhe_ok=$(grep -cE 'uses:\s*Fandhe-AI/actions/[^@[:space:]]+@latest([[:space:]]|#|$)' "$f") other_total=$((total - fandhe_total)) other_pinned=$(grep -E 'uses:' "$f" | grep -vE 'Fandhe-AI/actions/' \ | grep -cE 'uses:\s*[^@[:space:]]+@[0-9a-f]{40}([[:space:]]|#|$)' || true) if [ "$total" -eq 0 ]; then echo "NG: 検証対象の uses: 行が見つからない(workflow 生成に失敗している可能性)" >&2 exit 1 elif [ "$fandhe_total" -eq "$fandhe_ok" ] && [ "$other_total" -eq "$other_pinned" ]; then echo OK else echo "NG: 参照方式が不正な uses: 行がある(fandhe_total=${fandhe_total}, fandhe_ok=${fandhe_ok}, other_total=${other_total}, other_pinned=${other_pinned})" >&2 exit 1 fiOKが出力されること(uses:行が 1 件以上存在し、Fandhe-AI/actions/*行はすべて@latest、それ以外の行はすべて 40 桁 SHA 固定)。NG:が出力された場合は workflow の生成内容を見直すpermissionsが明示されていること:grep -c 'permissions:' .github/workflows/project-sync.ymlが 1 以上syncジョブにtimeout-minutesが設定されていること:grep -n 'timeout-minutes' .github/workflows/project-sync.ymlで 1 行以上ヒットする(欠落は CI ワークフロー規約違反・P1)
コミット・プッシュ後に GitHub Actions の実行履歴で初回トリガーが確認できれば完了。
モード B 完了後: Step B-7 の結果表で「変更なし: 0 件以上」が表示されていること。以下で最終状態を確認する:
gh project item-list <number> --owner <owner> --format json --limit 999
sandbox 環境での実行
このスキルはネットワーク越しの GitHub 操作(同期 workflow のコミット・プッシュ、gh project item-edit 等の一括補正)を必須とする。該当コマンドはコマンド単位で sandbox 無効にして実行する。ネットワーク遮断を解除できない環境では実行できない。
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/fandhe-ai/agent-cli-skills/project-sync-issues">View project-sync-issues on skillZs</a>