Managing tasks in GitHub Projects (Beta) is powerful — but adding a long list of draft issues manually? Tedious. In this post, I’ll show you how to automate the process using a simple PHP script and GitHub’s GraphQL API.
Whether you're planning a product roadmap, organising feature releases, or just bootstrapping a backlog — this workflow will save you hours.
✅ What You'll Learn
- How to create Draft Issues in GitHub Projects v2 using PHP
- How to use GraphQL for GitHub automation
- How to handle titles, descriptions, and client mutation IDs dynamically
📦 What You Need
- A GitHub Project (Beta) — created in your organisation or personal space.
- A GitHub Personal Access Token (PAT) — with at least the
project
scope. - Project Node ID — required for GraphQL mutations.
- PHP CLI with
curl
enabled.
🎯 Step 1: Get Your Project Node ID
GitHub Projects v2 uses GraphQL Node IDs, not plain numbers like /projects/2
.
Use the GitHub GraphQL Explorer and run this query:
query { organization(login: "your-org-name") { projectsV2(first: 10) { nodes { id number title } } } }
Replace your-org-name
with your actual GitHub org.
📝 Copy the id
where number
matches your project (e.g. 2).
🛠 Step 2: Write the PHP Script
Here’s a full working script to create Draft Issues with title and description:
<?php $githubToken = 'your_github_token_here'; // 🔐 GitHub PAT with `project` scope $projectId = 'PVT_your_project_node_id_here'; // 🆔 Project node ID $features = [ 'Jetstream Team Management', 'User Authentication', 'Soft Delete + UUID Support', // ... (more features) 'Priority Support System', ]; $apiUrl = 'https://api.github.com/graphql'; foreach ($features as $index => $title) { $body = "This is a placeholder description for **$title**.\n\nFeel free to update the details as needed."; $clientMutationId = uniqid("draft_"); $mutation = <<<GRAPHQL mutation { addProjectV2DraftIssue(input: { projectId: "$projectId", title: "$title", body: "$body", clientMutationId: "$clientMutationId" }) { projectItem { id } } } GRAPHQL; echo "📝 Creating draft: $title\n"; $response = githubGraphQL($apiUrl, $githubToken, $mutation); if (isset($response['data']['addProjectV2DraftIssue']['projectItem']['id'])) { echo "✅ Created: $title\n"; } else { echo "❌ Failed: $title\n"; print_r($response['errors'] ?? []); } } function githubGraphQL($url, $token, $query) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['query' => $query])); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer $token", "Content-Type: application/json", "User-Agent: PHP Script" ]); $response = curl_exec($ch); curl_close($ch); return json_decode($response, true); }
🚀 How to Run
- Save the file as
create-draft-issues.php
- Replace:
-
your_github_token_here
with your actual PAT -
PVT_your_project_node_id_here
with your actual Project ID- Run:
php create-draft-issues.php
💡 Use Cases
- 📋 Populate your GitHub project with your entire product backlog
- 🧪 Convert a spreadsheet of features into tasks
- 🔁 Use it in a CI/CD pipeline to bootstrap project boards
🔄 What’s Next?
Want to go further? You could:
- Parse CSV/Excel files to create issues dynamically
- Assign owners using
assigneeIds
- Add custom fields (like “Feature Type”) via
updateProjectV2ItemFieldValue
If you're building tools that interact with GitHub Projects at scale, GraphQL is the way to go.
🧵 Final Thoughts
Automation doesn’t have to be complex. This PHP-based approach makes it super easy to scaffold a GitHub Project in minutes.
If you’re managing your projects manually, this is your sign to automate it and focus more on shipping — not clicking.
✉️ Have any questions or want to see the Excel integration version next? Let me know!
Photo by Brands&People on Unsplash
Top comments (0)