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)