Automated Roadmap GitHub Action: Issue #1391

by ADMIN 45 views

Hey guys! Today, we're diving into an automated suggestion for issue #1391, focusing on the discussion category ni-sh-a-char and DekkhO. This is all about streamlining our workflow using a GitHub Action, so let's get started!

Next Steps: Setting Up the GitHub Action

The next crucial step is to add a minimal GitHub Action that automatically triggers on the labeled event, specifically when the roadmap label is applied to an issue. This is where the magic begins! This automated process helps in efficiently managing and prioritizing tasks within our project roadmap. By using GitHub Actions, we ensure that issues are promptly added to the roadmap, keeping everyone on the same page and reducing manual oversight. This not only saves time but also ensures consistency in our workflow, leading to better project management and faster progress.

YAML Configuration

First up, we need to create a .github/workflows/roadmap.yml file in our repository. This file will contain the configuration for our GitHub Action. Let's break down the YAML code:

# .github/workflows/roadmap.yml
name: Roadmap automation
on:
 issues:
 types: [labeled]

jobs:
 add-to-roadmap:
 if: github.event.label.name == 'roadmap'
 runs-on: ubuntu-latest
 steps:
 - name: Run automation script
 uses: actions/github-script@v7
 with:
 script: |
 const org = context.repo.owner;
 const projectName = 'DekkhO Roadmap';
 const issueNumber = context.payload.issue.number;
 const issueNodeId = context.payload.issue.node_id;
 const assignee = 'team-lead';
 const dueDate = '2025-10-15';

 // 1️⃣ Find or create the project
 let project = (await github.graphql(`
 query($org: String!, $name: String!) {
 organization(login: $org) {
 projectV2(name: $name) {
 id
 url
 }
 }
 }`, {org, name: projectName})).organization.projectV2;

 if (!project) {
 project = (await github.graphql(`
 mutation($org: String!, $name: String!) {
 createProjectV2(input:{ownerId: (SELECT id FROM organization WHERE login=$org), title:$name, public:false}) {
 projectV2 { id url }
 }
 }`, {org, name: projectName})).createProjectV2.projectV2;
 }

 // 2️⃣ Ensure a “To Do” column exists
 const columns = (await github.graphql(`
 query($projectId: ID!) {
 node(id: $projectId) {
 ... on ProjectV2 {
 fields(first: 100) {
 nodes {
 ... on ProjectV2SingleSelectField {
 name
 options
 }
 }
 }
 }
 }`, {projectId: project.id})).node.fields.nodes;

 const statusField = columns.find(f => f.name === 'Status');
 if (!statusField.options.includes('To Do')) {
 await github.graphql(`
 mutation($fieldId: ID!, $option: String!) {
 addProjectV2SingleSelectFieldOption(input:{projectId:$fieldId, fieldId:$fieldId, name:$option}) {
 projectV2SingleSelectFieldOption { id }
 }
 }`, {fieldId: statusField.id, option: 'To Do'});
 }

 // 3️⃣ Add the issue as a card and set status to “To Do”
 await github.graphql(`
 mutation($projectId: ID!, $contentId: ID!, $fieldId: ID!, $optionId: ID!) {
 addProjectV2ItemById(input:{projectId:$projectId, contentId:$contentId}) {
 item { id }
 }
 updateProjectV2ItemFieldValue(input:{
 projectId:$projectId,
 itemId:(SELECT id FROM projectV2Item WHERE contentId=$contentId),
 fieldId:$fieldId,
 value:{singleSelectOptionId:$optionId}
 }) {}
 }`, {
 projectId: project.id,
 contentId: issueNodeId,
 fieldId: statusField.id,
 optionId: statusField.options.find(o => o === 'To Do')
 });

 // 4️⃣ Assign the project to @team‑lead and set due date
 await github.graphql(`
 mutation($projectId: ID!, $assignee: String!, $due: Date!) {
 addProjectV2ItemById(input:{projectId:$projectId, contentId:$contentId}) {}
 updateProjectV2ItemFieldValue(input:{
 projectId:$projectId,
 itemId:(SELECT id FROM projectV2Item WHERE contentId=$contentId),
 fieldId:(SELECT id FROM projectV2Field WHERE name="Assignee"),
 value:{singleSelectOptionId:$assignee}
 }) {}
 updateProjectV2ItemFieldValue(input:{
 projectId:$projectId,
 itemId:(SELECT id FROM projectV2Item WHERE contentId=$contentId),
 fieldId:(SELECT id FROM projectV2Field WHERE name="Due date"),
 value:{date:$due}
 }) {}
 }`, {projectId: project.id, assignee, due: dueDate});

 // 5️⃣ Post confirmation comment
 await github.rest.issues.createComment({
 owner: org,
 repo: context.repo.repo,
 issue_number: issueNumber,
 body: '✅ Project board created and issue moved to **To Do**; due date set.'
 });

This YAML file defines a GitHub Action named “Roadmap automation”. It triggers when an issue is labeled, specifically looking for the roadmap label. The action then runs a script that:

  1. Finds or Creates the Project: The script first checks for an existing project named “DekkhO Roadmap.” If it doesn't exist, it creates a new project.
  2. Ensures a “To Do” Column Exists: It verifies if there's a “To Do” column in the project. If not, it adds one.
  3. Adds the Issue as a Card: The script adds the labeled issue as a card in the “To Do” column.
  4. Assigns the Project and Sets Due Date: It assigns the issue to @team-lead and sets a due date of 2025-10-15.
  5. Posts a Confirmation Comment: Finally, it posts a comment on the issue confirming that the project board has been created and the issue has been moved to the “To Do” column, with the due date set.

Why This Works: Breaking Down the Automation

Let’s dive deeper into why this automation script is so effective. It's not just about automating tasks; it's about creating a streamlined, efficient workflow that minimizes manual intervention and potential errors. Here’s a closer look at the key aspects:

  1. Trigger Mechanism: The action is triggered only when an issue gets the roadmap label. This targeted approach ensures that the automation runs precisely when needed, avoiding unnecessary executions and keeping our resources optimized. This specificity is crucial in maintaining a clean and efficient workflow.

  2. Idempotent Operation: The script intelligently checks for an existing “DekkhO Roadmap” project. If the project already exists, it won’t create a duplicate. This idempotent behavior is a critical feature that prevents accidental duplication and ensures the integrity of our project management system. It’s a smart way to handle automation, making it robust and reliable.

  3. Dynamic Column Handling: Ensuring a “To Do” status field exists might seem like a small detail, but it’s a significant step in maintaining consistency. The script guarantees that this column is available, which is essential for the proper categorization and tracking of tasks. This proactive handling of project structure ensures that every issue is correctly placed in our workflow from the start.

  4. Issue Placement and Status: Adding the issue as a card and setting its status to “To Do” is where the real magic happens. This step automates the process of adding new issues to our active task list. By setting the status immediately, we ensure that the issue is visible and ready for action, streamlining our workflow and reducing the time it takes to get tasks started.

  5. Ownership and Time Management: Setting the assignee to @team‑lead and the due date to 2025‑10‑15 is a powerful way to ensure accountability and time management. By automatically assigning ownership and setting deadlines, we reduce ambiguity and increase the likelihood of tasks being completed on time. This automation step is a key component in effective project management.

  6. Feedback Loop: Posting a concise comment confirming the actions is a fantastic way to keep everyone informed. This immediate feedback loop provides transparency and reassurance that the automation has run successfully. It’s a simple yet effective way to maintain clear communication and keep team members in the loop.

By automating these steps, we reduce the risk of human error, save valuable time, and ensure that our project management processes are consistent and reliable. This automation not only streamlines our workflow but also empowers our team to focus on higher-level tasks, driving productivity and innovation.

Next Actionable Step

Okay, guys, the next actionable step is pretty straightforward:

  • Add the workflow file (above) to your repository at .github/workflows/roadmap.yml.
  • Commit and push the changes.
  • Label any issue with roadmap to see the automation in action and verify it runs end-to-end.

Adjustments and Testing

If the GraphQL mutations need a little tweaking to match your organization’s field names (like “Assignee” versus a custom field), go ahead and adjust the field look-ups accordingly. Once you've verified everything, you can lock the workflow to workflow_dispatch for manual testing if you want to be extra cautious. Testing is key to ensuring our automation works flawlessly!

By implementing this GitHub Action, we’re taking a big step towards a more organized and efficient project workflow. Let’s get this set up and see how it transforms our process! Keep up the great work, everyone!